diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1040,7 +1040,8 @@ : SI->getFalseValue()); } else if (match(SI->getCondition(), m_ICmp(Pred, m_Specific(Op), m_Constant(C))) && - Pred == (IsTrueArm ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE)) { + Pred == (IsTrueArm ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) && + isGuaranteedNotToBeUndefOrPoison(C)) { // Pass } else { C = dyn_cast(Op); diff --git a/llvm/test/Transforms/InstCombine/binop-select.ll b/llvm/test/Transforms/InstCombine/binop-select.ll --- a/llvm/test/Transforms/InstCombine/binop-select.ll +++ b/llvm/test/Transforms/InstCombine/binop-select.ll @@ -6,6 +6,7 @@ declare void @use_v2f16(<2 x half>) declare void @use_v2i8(<2 x i8>) declare i32 @llvm.sadd.sat.i32(i32, i32) +declare <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8>, <2 x i8>) define i32 @test1(i1 %c, i32 %x, i32 %y) { ; CHECK-LABEL: @test1( @@ -109,6 +110,47 @@ ret i32 %sub } +define <2 x i8> @test_sub_dont_deduce_with_undef_cond_vec(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @test_sub_dont_deduce_with_undef_cond_vec( +; CHECK-NEXT: [[C_NOT:%.*]] = icmp eq <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[C_NOT]], <2 x i8> , <2 x i8> [[Y:%.*]] +; CHECK-NEXT: [[SUB:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[X]], <2 x i8> [[COND]]) +; CHECK-NEXT: ret <2 x i8> [[SUB]] +; + %c = icmp ne <2 x i8> %x, + %cond = select <2 x i1> %c, <2 x i8> %y, <2 x i8> + %sub = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %x, <2 x i8> %cond) + ret <2 x i8> %sub +} + +define <2 x i8> @test_sub_dont_deduce_with_poison_cond_vec(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @test_sub_dont_deduce_with_poison_cond_vec( +; CHECK-NEXT: [[C_NOT:%.*]] = icmp eq <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[C_NOT]], <2 x i8> , <2 x i8> [[Y:%.*]] +; CHECK-NEXT: [[SUB:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[X]], <2 x i8> [[COND]]) +; CHECK-NEXT: ret <2 x i8> [[SUB]] +; + %c = icmp ne <2 x i8> %x, + %cond = select <2 x i1> %c, <2 x i8> %y, <2 x i8> + %sub = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %x, <2 x i8> %cond) + ret <2 x i8> %sub +} + + +define <2 x i8> @test_sub_deduce_with_undef_val_vec(<2 x i8> %x, <2 x i8> %y) { +; CHECK-LABEL: @test_sub_deduce_with_undef_val_vec( +; CHECK-NEXT: [[C_NOT:%.*]] = icmp eq <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> [[X]], <2 x i8> [[Y:%.*]]) +; CHECK-NEXT: [[SUB:%.*]] = select <2 x i1> [[C_NOT]], <2 x i8> , <2 x i8> [[TMP1]] +; CHECK-NEXT: ret <2 x i8> [[SUB]] +; + %c = icmp ne <2 x i8> %x, + %cond = select <2 x i1> %c, <2 x i8> %y, <2 x i8> + %sub = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %x, <2 x i8> %cond) + ret <2 x i8> %sub +} + + define i32 @test6(i1 %c, i32 %x, i32 %y) { ; CHECK-LABEL: @test6( ; CHECK-NEXT: [[COND:%.*]] = select i1 [[C:%.*]], i32 7, i32 [[X:%.*]]