Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1380,8 +1380,8 @@ // (add (and A, B) (or A, B)) --> (add A, B) if (match(&I, m_c_BinOp(m_Or(m_Value(A), m_Value(B)), m_c_And(m_Deferred(A), m_Deferred(B))))) { - I.setOperand(0, A); - I.setOperand(1, B); + replaceOperand(I, 0, A); + replaceOperand(I, 1, B); return &I; } Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2742,33 +2742,24 @@ // (A | B) ^ (A & B) -> A ^ B // (A | B) ^ (B & A) -> A ^ B if (match(&I, m_c_Xor(m_And(m_Value(A), m_Value(B)), - m_c_Or(m_Deferred(A), m_Deferred(B))))) { - I.setOperand(0, A); - I.setOperand(1, B); - return &I; - } + m_c_Or(m_Deferred(A), m_Deferred(B))))) + return BinaryOperator::CreateXor(A, B); // (A | ~B) ^ (~A | B) -> A ^ B // (~B | A) ^ (~A | B) -> A ^ B // (~A | B) ^ (A | ~B) -> A ^ B // (B | ~A) ^ (A | ~B) -> A ^ B if (match(&I, m_Xor(m_c_Or(m_Value(A), m_Not(m_Value(B))), - m_c_Or(m_Not(m_Deferred(A)), m_Deferred(B))))) { - I.setOperand(0, A); - I.setOperand(1, B); - return &I; - } + m_c_Or(m_Not(m_Deferred(A)), m_Deferred(B))))) + return BinaryOperator::CreateXor(A, B); // (A & ~B) ^ (~A & B) -> A ^ B // (~B & A) ^ (~A & B) -> A ^ B // (~A & B) ^ (A & ~B) -> A ^ B // (B & ~A) ^ (A & ~B) -> A ^ B if (match(&I, m_Xor(m_c_And(m_Value(A), m_Not(m_Value(B))), - m_c_And(m_Not(m_Deferred(A)), m_Deferred(B))))) { - I.setOperand(0, A); - I.setOperand(1, B); - return &I; - } + m_c_And(m_Not(m_Deferred(A)), m_Deferred(B))))) + return BinaryOperator::CreateXor(A, B); // For the remaining cases we need to get rid of one of the operands. if (!Op0->hasOneUse() && !Op1->hasOneUse()) @@ -3108,10 +3099,7 @@ if (match(Op0, m_Or(m_Value(X), m_APInt(C))) && MaskedValueIsZero(X, *C, 0, &I)) { Constant *NewC = ConstantInt::get(I.getType(), *C ^ *RHSC); - Worklist.push(cast(Op0)); - I.setOperand(0, X); - I.setOperand(1, NewC); - return &I; + return BinaryOperator::CreateXor(X, NewC); } } } Index: llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp @@ -138,13 +138,11 @@ if (RMWI.getType()->isIntegerTy() && RMWI.getOperation() != AtomicRMWInst::Or) { RMWI.setOperation(AtomicRMWInst::Or); - RMWI.setOperand(1, ConstantInt::get(RMWI.getType(), 0)); - return &RMWI; + return replaceOperand(RMWI, 1, ConstantInt::get(RMWI.getType(), 0)); } else if (RMWI.getType()->isFloatingPointTy() && RMWI.getOperation() != AtomicRMWInst::FAdd) { RMWI.setOperation(AtomicRMWInst::FAdd); - RMWI.setOperand(1, ConstantFP::getNegativeZero(RMWI.getType())); - return &RMWI; + return replaceOperand(RMWI, 1, ConstantFP::getNegativeZero(RMWI.getType())); } // Check if the required ordering is compatible with an atomic load. Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1680,12 +1680,11 @@ if (Cmp.getPredicate() == ICmpInst::ICMP_NE) return replaceInstUsesWith(Cmp, ConstantInt::getTrue(Cmp.getType())); } else { - Cmp.setOperand(1, ConstantInt::get(And->getType(), NewCst)); APInt NewAndCst = IsShl ? C2.lshr(*C3) : C2.shl(*C3); - And->setOperand(1, ConstantInt::get(And->getType(), NewAndCst)); - And->setOperand(0, Shift->getOperand(0)); - Worklist.push(Shift); // Shift is dead. - return &Cmp; + Value *NewAnd = Builder.CreateAnd( + Shift->getOperand(0), ConstantInt::get(And->getType(), NewAndCst)); + return new ICmpInst(Cmp.getPredicate(), + NewAnd, ConstantInt::get(And->getType(), NewCst)); } } } @@ -4154,9 +4153,7 @@ if (X) { // Build (X^Y) & Z Op1 = Builder.CreateXor(X, Y); Op1 = Builder.CreateAnd(Op1, Z); - I.setOperand(0, Op1); - I.setOperand(1, Constant::getNullValue(Op1->getType())); - return &I; + return new ICmpInst(Pred, Op1, Constant::getNullValue(Op1->getType())); } } @@ -6026,14 +6023,11 @@ // If we're just checking for a NaN (ORD/UNO) and have a non-NaN operand, // then canonicalize the operand to 0.0. if (Pred == CmpInst::FCMP_ORD || Pred == CmpInst::FCMP_UNO) { - if (!match(Op0, m_PosZeroFP()) && isKnownNeverNaN(Op0, &TLI)) { - I.setOperand(0, ConstantFP::getNullValue(OpType)); - return &I; - } - if (!match(Op1, m_PosZeroFP()) && isKnownNeverNaN(Op1, &TLI)) { - I.setOperand(1, ConstantFP::getNullValue(OpType)); - return &I; - } + if (!match(Op0, m_PosZeroFP()) && isKnownNeverNaN(Op0, &TLI)) + return replaceOperand(I, 0, ConstantFP::getNullValue(OpType)); + + if (!match(Op1, m_PosZeroFP()) && isKnownNeverNaN(Op1, &TLI)) + return replaceOperand(I, 1, ConstantFP::getNullValue(OpType)); } // fcmp pred (fneg X), (fneg Y) -> fcmp swap(pred) X, Y @@ -6058,10 +6052,8 @@ // The sign of 0.0 is ignored by fcmp, so canonicalize to +0.0: // fcmp Pred X, -0.0 --> fcmp Pred X, 0.0 - if (match(Op1, m_AnyZeroFP()) && !match(Op1, m_PosZeroFP())) { - I.setOperand(1, ConstantFP::getNullValue(OpType)); - return &I; - } + if (match(Op1, m_AnyZeroFP()) && !match(Op1, m_PosZeroFP())) + return replaceOperand(I, 1, ConstantFP::getNullValue(OpType)); // Handle fcmp with instruction LHS and constant RHS. Instruction *LHSI; Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -56,7 +56,8 @@ /// Replace a select operand based on an equality comparison with the identity /// constant of a binop. static Instruction *foldSelectBinOpIdentity(SelectInst &Sel, - const TargetLibraryInfo &TLI) { + const TargetLibraryInfo &TLI, + InstCombiner &IC) { // The select condition must be an equality compare with a constant operand. Value *X; Constant *C; @@ -107,8 +108,7 @@ // S = { select (cmp eq X, C), BO, ? } or { select (cmp ne X, C), ?, BO } // => // S = { select (cmp eq X, C), Y, ? } or { select (cmp ne X, C), ?, Y } - Sel.setOperand(IsEq ? 1 : 2, Y); - return &Sel; + return IC.replaceOperand(Sel, IsEq ? 1 : 2, Y); } /// This folds: @@ -997,7 +997,7 @@ /// constant operand of the select. static Instruction * canonicalizeMinMaxWithConstant(SelectInst &Sel, ICmpInst &Cmp, - InstCombiner::BuilderTy &Builder) { + InstCombiner &IC) { if (!Cmp.hasOneUse() || !isa(Cmp.getOperand(1))) return nullptr; @@ -1014,7 +1014,7 @@ return nullptr; // Create the canonical compare and plug it into the select. - Sel.setCondition(Builder.CreateICmp(CanonicalPred, LHS, RHS)); + IC.replaceOperand(Sel, 0, IC.Builder.CreateICmp(CanonicalPred, LHS, RHS)); // If the select operands did not change, we're done. if (Sel.getTrueValue() == LHS && Sel.getFalseValue() == RHS) @@ -1322,7 +1322,7 @@ // and swap the hands of select. static Instruction * tryToReuseConstantFromSelectInComparison(SelectInst &Sel, ICmpInst &Cmp, - InstCombiner::BuilderTy &Builder) { + InstCombiner &IC) { ICmpInst::Predicate Pred; Value *X; Constant *C0; @@ -1374,13 +1374,13 @@ return nullptr; // It matched! Lets insert the new comparison just before select. - InstCombiner::BuilderTy::InsertPointGuard Guard(Builder); - Builder.SetInsertPoint(&Sel); + InstCombiner::BuilderTy::InsertPointGuard Guard(IC.Builder); + IC.Builder.SetInsertPoint(&Sel); Pred = ICmpInst::getSwappedPredicate(Pred); // Yes, swapped. - Value *NewCmp = Builder.CreateICmp(Pred, X, FlippedStrictness->second, - Cmp.getName() + ".inv"); - Sel.setCondition(NewCmp); + Value *NewCmp = IC.Builder.CreateICmp(Pred, X, FlippedStrictness->second, + Cmp.getName() + ".inv"); + IC.replaceOperand(Sel, 0, NewCmp); Sel.swapValues(); Sel.swapProfMetadata(); @@ -1393,7 +1393,7 @@ if (Value *V = foldSelectValueEquivalence(SI, *ICI, SQ)) return replaceInstUsesWith(SI, V); - if (Instruction *NewSel = canonicalizeMinMaxWithConstant(SI, *ICI, Builder)) + if (Instruction *NewSel = canonicalizeMinMaxWithConstant(SI, *ICI, *this)) return NewSel; if (Instruction *NewAbs = canonicalizeAbsNabs(SI, *ICI, Builder)) @@ -1403,7 +1403,7 @@ return NewAbs; if (Instruction *NewSel = - tryToReuseConstantFromSelectInComparison(SI, *ICI, Builder)) + tryToReuseConstantFromSelectInComparison(SI, *ICI, *this)) return NewSel; bool Changed = adjustMinMax(SI, *ICI); @@ -1966,7 +1966,7 @@ /// other operations in IR and having all operands of a select be vector types /// is likely better for vector codegen. static Instruction *canonicalizeScalarSelectOfVecs( - SelectInst &Sel, InstCombiner::BuilderTy &Builder) { + SelectInst &Sel, InstCombiner &IC) { Type *Ty = Sel.getType(); if (!Ty->isVectorTy()) return nullptr; @@ -1980,9 +1980,7 @@ // Splatting the extracted condition reduces code (we could directly create a // splat shuffle of the source vector to eliminate the intermediate step). unsigned NumElts = Ty->getVectorNumElements(); - Value *SplatCond = Builder.CreateVectorSplat(NumElts, Cond); - Sel.setCondition(SplatCond); - return &Sel; + return IC.replaceOperand(Sel, 0, IC.Builder.CreateVectorSplat(NumElts, Cond)); } /// Reuse bitcasted operands between a compare and select: @@ -2388,7 +2386,7 @@ if (Instruction *I = canonicalizeSelectToShuffle(SI)) return I; - if (Instruction *I = canonicalizeScalarSelectOfVecs(SI, Builder)) + if (Instruction *I = canonicalizeScalarSelectOfVecs(SI, *this)) return I; // Canonicalize a one-use integer compare with a non-canonical predicate by @@ -2401,8 +2399,7 @@ // Swap true/false values and condition. CmpInst *Cond = cast(CondVal); Cond->setPredicate(CmpInst::getInversePredicate(Pred)); - SI.setOperand(1, FalseVal); - SI.setOperand(2, TrueVal); + SI.swapValues(); SI.swapProfMetadata(); Worklist.push(Cond); return &SI; @@ -2692,8 +2689,7 @@ if (TrueSI->getCondition() == CondVal) { if (SI.getTrueValue() == TrueSI->getTrueValue()) return nullptr; - SI.setOperand(1, TrueSI->getTrueValue()); - return &SI; + return replaceOperand(SI, 1, TrueSI->getTrueValue()); } // select(C0, select(C1, a, b), b) -> select(C0&C1, a, b) // We choose this as normal form to enable folding on the And and shortening @@ -2712,8 +2708,7 @@ if (FalseSI->getCondition() == CondVal) { if (SI.getFalseValue() == FalseSI->getFalseValue()) return nullptr; - SI.setOperand(2, FalseSI->getFalseValue()); - return &SI; + return replaceOperand(SI, 2, FalseSI->getFalseValue()); } // select(C0, a, select(C1, a, b)) -> select(C0|C1, a, b) if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) { @@ -2782,9 +2777,8 @@ Value *NotCond; if (match(CondVal, m_Not(m_Value(NotCond)))) { - SI.setOperand(0, NotCond); - SI.setOperand(1, FalseVal); - SI.setOperand(2, TrueVal); + replaceOperand(SI, 0, NotCond); + SI.swapValues(); SI.swapProfMetadata(); return &SI; } @@ -2821,7 +2815,7 @@ if (Instruction *Select = foldSelectCmpXchg(SI)) return Select; - if (Instruction *Select = foldSelectBinOpIdentity(SI, TLI)) + if (Instruction *Select = foldSelectBinOpIdentity(SI, TLI, *this)) return Select; if (Instruction *Rot = foldSelectRotate(SI)) Index: llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -388,8 +388,7 @@ // demand the sign bit (and many others) here?? Value *Rem = Builder.CreateAnd(A, ConstantInt::get(I.getType(), *B - 1), Op1->getName()); - I.setOperand(1, Rem); - return &I; + return replaceOperand(I, 1, Rem); } if (Instruction *Logic = foldShiftOfShiftedLogic(I, Builder)) Index: llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -1739,7 +1739,8 @@ /// Try to replace a shuffle with an insertelement or try to replace a shuffle /// operand with the operand of an insertelement. -static Instruction *foldShuffleWithInsert(ShuffleVectorInst &Shuf) { +static Instruction *foldShuffleWithInsert(ShuffleVectorInst &Shuf, + InstCombiner &IC) { Value *V0 = Shuf.getOperand(0), *V1 = Shuf.getOperand(1); SmallVector Mask = Shuf.getShuffleMask(); @@ -1759,20 +1760,16 @@ uint64_t IdxC; if (match(V0, m_InsertElement(m_Value(X), m_Value(), m_ConstantInt(IdxC)))) { // shuf (inselt X, ?, IdxC), ?, Mask --> shuf X, ?, Mask - if (none_of(Mask, [IdxC](int MaskElt) { return MaskElt == (int)IdxC; })) { - Shuf.setOperand(0, X); - return &Shuf; - } + if (none_of(Mask, [IdxC](int MaskElt) { return MaskElt == (int)IdxC; })) + return IC.replaceOperand(Shuf, 0, X); } if (match(V1, m_InsertElement(m_Value(X), m_Value(), m_ConstantInt(IdxC)))) { // Offset the index constant by the vector width because we are checking for // accesses to the 2nd vector input of the shuffle. IdxC += NumElts; // shuf ?, (inselt X, ?, IdxC), Mask --> shuf ?, X, Mask - if (none_of(Mask, [IdxC](int MaskElt) { return MaskElt == (int)IdxC; })) { - Shuf.setOperand(1, X); - return &Shuf; - } + if (none_of(Mask, [IdxC](int MaskElt) { return MaskElt == (int)IdxC; })) + return IC.replaceOperand(Shuf, 1, X); } // shuffle (insert ?, Scalar, IndexC), V1, Mask --> insert V1, Scalar, IndexC' @@ -1917,10 +1914,8 @@ else Elts.push_back(ConstantInt::get(Int32Ty, Mask[i] % LHSWidth)); } - SVI.setOperand(0, SVI.getOperand(1)); - SVI.setOperand(1, UndefValue::get(RHS->getType())); - SVI.setOperand(2, ConstantVector::get(Elts)); - return &SVI; + return new ShuffleVectorInst(LHS, UndefValue::get(RHS->getType()), + ConstantVector::get(Elts)); } // shuffle undef, x, mask --> shuffle x, undef, mask' @@ -1951,7 +1946,7 @@ // These transforms have the potential to lose undef knowledge, so they are // intentionally placed after SimplifyDemandedVectorElts(). - if (Instruction *I = foldShuffleWithInsert(SVI)) + if (Instruction *I = foldShuffleWithInsert(SVI, *this)) return I; if (Instruction *I = foldIdentityPaddedShuffles(SVI)) return I; Index: llvm/test/Transforms/InstCombine/icmp-custom-dl.ll =================================================================== --- llvm/test/Transforms/InstCombine/icmp-custom-dl.ll +++ llvm/test/Transforms/InstCombine/icmp-custom-dl.ll @@ -183,10 +183,10 @@ ; Variation of the above with an ashr define i1 @icmp_and_ashr_multiuse(i32 %X) { ; CHECK-LABEL: @icmp_and_ashr_multiuse( -; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240 -; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496 -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224 -; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 +; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496 +; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] ; CHECK-NEXT: ret i1 [[AND3]] ; Index: llvm/test/Transforms/InstCombine/icmp.ll =================================================================== --- llvm/test/Transforms/InstCombine/icmp.ll +++ llvm/test/Transforms/InstCombine/icmp.ll @@ -98,8 +98,8 @@ define i32 @test6(i32 %a, i32 %b) { ; CHECK-LABEL: @test6( -; CHECK-NEXT: [[E:%.*]] = ashr i32 [[A:%.*]], 31 -; CHECK-NEXT: [[F:%.*]] = and i32 [[E]], [[B:%.*]] +; CHECK-NEXT: [[A_LOBIT_NEG:%.*]] = ashr i32 [[A:%.*]], 31 +; CHECK-NEXT: [[F:%.*]] = and i32 [[A_LOBIT_NEG]], [[B:%.*]] ; CHECK-NEXT: ret i32 [[F]] ; %c = icmp sle i32 %a, -1 @@ -1775,8 +1775,8 @@ define i1 @icmp_add_and_shr_ne_0(i32 %X) { ; CHECK-LABEL: @icmp_add_and_shr_ne_0( -; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240 -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 ; CHECK-NEXT: ret i1 [[TOBOOL]] ; %shr = lshr i32 %X, 4 @@ -1788,8 +1788,8 @@ define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) { ; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec( -; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[AND]], +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP1]], ; CHECK-NEXT: ret <2 x i1> [[TOBOOL]] ; %shr = lshr <2 x i32> %X, @@ -1802,10 +1802,10 @@ ; Variation of the above with an extra use of the shift define i1 @icmp_and_shr_multiuse(i32 %X) { ; CHECK-LABEL: @icmp_and_shr_multiuse( -; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240 -; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496 -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224 -; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 +; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496 +; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] ; CHECK-NEXT: ret i1 [[AND3]] ; @@ -1821,10 +1821,10 @@ ; Variation of the above with an ashr define i1 @icmp_and_ashr_multiuse(i32 %X) { ; CHECK-LABEL: @icmp_and_ashr_multiuse( -; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240 -; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496 -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224 -; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224 +; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496 +; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]] ; CHECK-NEXT: ret i1 [[AND3]] ;