diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 3f780285efe42..be2f2fdd66997 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -4213,22 +4213,36 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) { }); SimplifyQuery Q = SQ.getWithInstruction(&SI).getWithCondContext(CC); if (!CC.AffectedValues.empty()) { - if (!isa(TrueVal) && - hasAffectedValue(TrueVal, CC.AffectedValues, /*Depth=*/0)) { - KnownBits Known = llvm::computeKnownBits(TrueVal, /*Depth=*/0, Q); - if (Known.isConstant()) - return replaceOperand(SI, 1, - ConstantInt::get(SelType, Known.getConstant())); - } + std::optional NotUndef; + auto SimplifyOp = [&](unsigned OpNum) -> Instruction * { + Value *V = SI.getOperand(OpNum); + if (isa(V) || + !hasAffectedValue(V, CC.AffectedValues, /*Depth=*/0)) + return nullptr; + + if (!NotUndef) + NotUndef = isGuaranteedNotToBeUndef(CondVal); + if (*NotUndef) { + unsigned BitWidth = SelType->getScalarSizeInBits(); + KnownBits Known(BitWidth); + if (SimplifyDemandedBits(&SI, OpNum, APInt::getAllOnes(BitWidth), + Known, /*Depth=*/0, Q)) + return &SI; + } else { + KnownBits Known = llvm::computeKnownBits(V, /*Depth=*/0, Q); + if (Known.isConstant()) + return replaceOperand( + SI, OpNum, ConstantInt::get(SelType, Known.getConstant())); + } + return nullptr; + }; + + if (Instruction *Res = SimplifyOp(1)) + return Res; CC.Invert = true; - if (!isa(FalseVal) && - hasAffectedValue(FalseVal, CC.AffectedValues, /*Depth=*/0)) { - KnownBits Known = llvm::computeKnownBits(FalseVal, /*Depth=*/0, Q); - if (Known.isConstant()) - return replaceOperand(SI, 2, - ConstantInt::get(SelType, Known.getConstant())); - } + if (Instruction *Res = SimplifyOp(2)) + return Res; } } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index ee6b60f7f70d6..29efd8462cb28 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -320,6 +320,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I, // bits on that side are also known to be set on the other side, turn this // into an AND, as we know the bits will be cleared. // e.g. (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2 +#if 0 if (DemandedMask.isSubsetOf(RHSKnown.Zero|RHSKnown.One) && RHSKnown.One.isSubsetOf(LHSKnown.One)) { Constant *AndC = Constant::getIntegerValue(VTy, @@ -327,6 +328,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I, Instruction *And = BinaryOperator::CreateAnd(I->getOperand(0), AndC); return InsertNewInstWith(And, I->getIterator()); } +#endif // If the RHS is a constant, see if we can change it. Don't alter a -1 // constant because that's a canonical 'not' op, and that is better for diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll index 417c3a950d780..12e55557d504a 100644 --- a/llvm/test/Transforms/InstCombine/add.ll +++ b/llvm/test/Transforms/InstCombine/add.ll @@ -1196,8 +1196,8 @@ define i32 @add_to_sub2(i32 %A, i32 %M) { ; (X | C1) + C2 --> (X | C1) ^ C1 iff (C1 == -C2) define i32 @test44(i32 %A) { ; CHECK-LABEL: @test44( -; CHECK-NEXT: [[C:%.*]] = and i32 [[A:%.*]], -124 -; CHECK-NEXT: ret i32 [[C]] +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], -124 +; CHECK-NEXT: ret i32 [[TMP1]] ; %B = or i32 %A, 123 %C = add i32 %B, -123 @@ -1207,7 +1207,7 @@ define i32 @test44(i32 %A) { define i32 @test44_extra_use(i32 %A) { ; CHECK-LABEL: @test44_extra_use( ; CHECK-NEXT: [[B:%.*]] = or i32 [[A:%.*]], 123 -; CHECK-NEXT: [[C:%.*]] = and i32 [[A]], -124 +; CHECK-NEXT: [[C:%.*]] = xor i32 [[B]], 123 ; CHECK-NEXT: [[D:%.*]] = mul i32 [[B]], [[C]] ; CHECK-NEXT: ret i32 [[D]] ; @@ -1230,8 +1230,8 @@ define i32 @test44_non_matching(i32 %A) { define <2 x i32> @test44_vec(<2 x i32> %A) { ; CHECK-LABEL: @test44_vec( -; CHECK-NEXT: [[C:%.*]] = and <2 x i32> [[A:%.*]], -; CHECK-NEXT: ret <2 x i32> [[C]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], +; CHECK-NEXT: ret <2 x i32> [[TMP1]] ; %B = or <2 x i32> %A, %C = add <2 x i32> %B, diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index 7d62b41942440..d66bab4c0b4e3 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -2989,9 +2989,8 @@ define i8 @select_replacement_loop3(i32 noundef %x) { define i16 @select_replacement_loop4(i16 noundef %p_12) { ; CHECK-LABEL: @select_replacement_loop4( -; CHECK-NEXT: [[AND1:%.*]] = and i16 [[P_12:%.*]], 1 -; CHECK-NEXT: [[CMP21:%.*]] = icmp ult i16 [[P_12]], 2 -; CHECK-NEXT: [[AND3:%.*]] = select i1 [[CMP21]], i16 [[AND1]], i16 0 +; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i16 [[P_12:%.*]], 2 +; CHECK-NEXT: [[AND3:%.*]] = select i1 [[CMP1]], i16 [[P_12]], i16 0 ; CHECK-NEXT: ret i16 [[AND3]] ; %cmp1 = icmp ult i16 %p_12, 2 @@ -4671,8 +4670,7 @@ define i8 @select_knownbits_simplify(i8 noundef %x) { ; CHECK-LABEL: @select_knownbits_simplify( ; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0 -; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2 -; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0 +; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[X]], i8 0 ; CHECK-NEXT: ret i8 [[RES]] ; %x.lo = and i8 %x, 1 @@ -4686,8 +4684,7 @@ define i8 @select_knownbits_simplify_nested(i8 noundef %x) { ; CHECK-LABEL: @select_knownbits_simplify_nested( ; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X:%.*]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0 -; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2 -; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[AND]], [[AND]] +; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[X]], [[X]] ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 0 ; CHECK-NEXT: ret i8 [[RES]] ;