diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 9e3e739fae3d..36f413645761 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -841,6 +841,8 @@ Constant *Constant::mergeUndefsWith(Constant *C, Constant *Other) { } bool Constant::isManifestConstant() const { + if (isa(this)) + return false; if (isa(this)) return true; if (isa(this) || isa(this)) { diff --git a/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll b/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll index 32bd2fff2732..2801c3d2a977 100644 --- a/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll +++ b/llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll @@ -120,3 +120,21 @@ define i1 @global_array() { %1 = call i1 @llvm.is.constant.i64(i64 ptrtoint (ptr @real_mode_blob_end to i64)) ret i1 %1 } + +;; Ensure that is.constant of undef gets lowered reasonably to "false" in +;; optimized codegen: specifically that the "true" branch is eliminated. +;; CHECK-NOT: tail call i32 @subfun_1() +;; CHECK: tail call i32 @subfun_2() +;; CHECK-NOT: tail call i32 @subfun_1() +define i32 @test_undef_branch() nounwind { + %v = call i1 @llvm.is.constant.i32(i32 undef) + br i1 %v, label %True, label %False + +True: + %call1 = tail call i32 @subfun_1() + ret i32 %call1 + +False: + %call2 = tail call i32 @subfun_2() + ret i32 %call2 +}