diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4640,7 +4640,8 @@ if (auto *CondC = dyn_cast(Cond)) { if (auto *TrueC = dyn_cast(TrueVal)) if (auto *FalseC = dyn_cast(FalseVal)) - return ConstantFoldSelectInstruction(CondC, TrueC, FalseC); + if (Constant *C = ConstantFoldSelectInstruction(CondC, TrueC, FalseC)) + return C; // select poison, X, Y -> poison if (isa(CondC)) diff --git a/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll b/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll --- a/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll +++ b/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll @@ -881,11 +881,19 @@ ret <2 x float> %s } -; Negative tests. Don't fold if the non-undef operand is a constexpr. +@a = external global [3 x ptr] +define i32 @all_constant_false_undef_true_poison_gen_constexpr(i1 %a) { +; CHECK-LABEL: @all_constant_false_undef_true_poison_gen_constexpr( +; CHECK-NEXT: [[S:%.*]] = select i1 [[A:%.*]], i32 ptrtoint (ptr getelementptr inbounds ([3 x ptr], ptr @a, i64 2) to i32), i32 undef +; CHECK-NEXT: ret i32 [[S]] +; + %s = select i1 %a, i32 ptrtoint (ptr getelementptr inbounds ([3 x ptr], ptr @a, i64 2) to i32), i32 undef + ret i32 %s +} + define i32 @all_constant_false_undef_true_constexpr() { ; CHECK-LABEL: @all_constant_false_undef_true_constexpr( -; CHECK-NEXT: [[S:%.*]] = select i1 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i1), i32 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i32), i32 undef -; CHECK-NEXT: ret i32 [[S]] +; CHECK-NEXT: ret i32 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i32) ; %s = select i1 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i1), i32 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i32), i32 undef ret i32 %s @@ -893,8 +901,7 @@ define i32 @all_constant_true_undef_false_constexpr() { ; CHECK-LABEL: @all_constant_true_undef_false_constexpr( -; CHECK-NEXT: [[S:%.*]] = select i1 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i1), i32 undef, i32 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i32) -; CHECK-NEXT: ret i32 [[S]] +; CHECK-NEXT: ret i32 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i32) ; %s = select i1 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i1), i32 undef, i32 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i32) ret i32 %s @@ -903,8 +910,7 @@ ; Negative tests. Don't fold if the non-undef operand is a vector containing a constexpr. define <2 x i32> @all_constant_false_undef_true_constexpr_vec() { ; CHECK-LABEL: @all_constant_false_undef_true_constexpr_vec( -; CHECK-NEXT: [[S:%.*]] = select i1 ptrtoint (ptr @all_constant_false_undef_true_constexpr_vec to i1), <2 x i32> , <2 x i32> undef -; CHECK-NEXT: ret <2 x i32> [[S]] +; CHECK-NEXT: ret <2 x i32> ; %s = select i1 ptrtoint (ptr @all_constant_false_undef_true_constexpr_vec to i1), <2 x i32> , <2 x i32> undef ret <2 x i32> %s @@ -912,8 +918,7 @@ define <2 x i32> @all_constant_true_undef_false_constexpr_vec() { ; CHECK-LABEL: @all_constant_true_undef_false_constexpr_vec( -; CHECK-NEXT: [[S:%.*]] = select i1 ptrtoint (ptr @all_constant_true_undef_false_constexpr_vec to i1), <2 x i32> undef, <2 x i32> -; CHECK-NEXT: ret <2 x i32> [[S]] +; CHECK-NEXT: ret <2 x i32> ; %s = select i1 ptrtoint (ptr @all_constant_true_undef_false_constexpr_vec to i1), <2 x i32> undef, <2 x i32> ret <2 x i32> %s diff --git a/llvm/test/Transforms/InstSimplify/select.ll b/llvm/test/Transforms/InstSimplify/select.ll --- a/llvm/test/Transforms/InstSimplify/select.ll +++ b/llvm/test/Transforms/InstSimplify/select.ll @@ -9,6 +9,14 @@ ret i1 %s } +define i1 @cond_constexpr_bool_true_or_false(i1 %cond) { +; CHECK-LABEL: @cond_constexpr_bool_true_or_false( +; CHECK-NEXT: ret i1 ptrtoint (ptr @cond_constexpr_bool_true_or_false to i1) +; + %s = select i1 ptrtoint (ptr @cond_constexpr_bool_true_or_false to i1), i1 true, i1 false + ret i1 %s +} + define <2 x i1> @bool_true_or_false_vec(<2 x i1> %cond) { ; CHECK-LABEL: @bool_true_or_false_vec( ; CHECK-NEXT: ret <2 x i1> [[COND:%.*]] @@ -884,8 +892,7 @@ ; Negative tests. Don't fold if the non-undef operand is a constexpr. define i32 @all_constant_false_undef_true_constexpr() { ; CHECK-LABEL: @all_constant_false_undef_true_constexpr( -; CHECK-NEXT: [[S:%.*]] = select i1 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i1), i32 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i32), i32 undef -; CHECK-NEXT: ret i32 [[S]] +; CHECK-NEXT: ret i32 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i32) ; %s = select i1 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i1), i32 ptrtoint (ptr @all_constant_false_undef_true_constexpr to i32), i32 undef ret i32 %s @@ -893,8 +900,7 @@ define i32 @all_constant_true_undef_false_constexpr() { ; CHECK-LABEL: @all_constant_true_undef_false_constexpr( -; CHECK-NEXT: [[S:%.*]] = select i1 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i1), i32 undef, i32 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i32) -; CHECK-NEXT: ret i32 [[S]] +; CHECK-NEXT: ret i32 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i32) ; %s = select i1 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i1), i32 undef, i32 ptrtoint (ptr @all_constant_true_undef_false_constexpr to i32) ret i32 %s @@ -903,8 +909,7 @@ ; Negative tests. Don't fold if the non-undef operand is a vector containing a constexpr. define <2 x i32> @all_constant_false_undef_true_constexpr_vec() { ; CHECK-LABEL: @all_constant_false_undef_true_constexpr_vec( -; CHECK-NEXT: [[S:%.*]] = select i1 ptrtoint (ptr @all_constant_false_undef_true_constexpr_vec to i1), <2 x i32> , <2 x i32> undef -; CHECK-NEXT: ret <2 x i32> [[S]] +; CHECK-NEXT: ret <2 x i32> ; %s = select i1 ptrtoint (ptr @all_constant_false_undef_true_constexpr_vec to i1), <2 x i32> , <2 x i32> undef ret <2 x i32> %s @@ -912,8 +917,7 @@ define <2 x i32> @all_constant_true_undef_false_constexpr_vec() { ; CHECK-LABEL: @all_constant_true_undef_false_constexpr_vec( -; CHECK-NEXT: [[S:%.*]] = select i1 ptrtoint (ptr @all_constant_true_undef_false_constexpr_vec to i1), <2 x i32> undef, <2 x i32> -; CHECK-NEXT: ret <2 x i32> [[S]] +; CHECK-NEXT: ret <2 x i32> ; %s = select i1 ptrtoint (ptr @all_constant_true_undef_false_constexpr_vec to i1), <2 x i32> undef, <2 x i32> ret <2 x i32> %s