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 @@ -633,8 +633,8 @@ // X + ~X -> -1 since ~X = -X-1 Type *Ty = Op0->getType(); - if (match(Op0, m_Not(m_Specific(Op1))) || - match(Op1, m_Not(m_Specific(Op0)))) + if (Q.AllowRefinement && (match(Op0, m_Not(m_Specific(Op1))) || + match(Op1, m_Not(m_Specific(Op0))))) return Constant::getAllOnesValue(Ty); // add nsw/nuw (xor Y, signmask), signmask --> Y @@ -753,7 +753,7 @@ return Op0; // X - X -> 0 - if (Op0 == Op1) + if (Q.AllowRefinement && Op0 == Op1) return Constant::getNullValue(Op0->getType()); // Is this a negation? @@ -1314,7 +1314,7 @@ return V; // X >> X -> 0 - if (Op0 == Op1) + if (Q.AllowRefinement && Op0 == Op1) return Constant::getNullValue(Op0->getType()); // undef >> X -> 0 @@ -1413,7 +1413,7 @@ // all ones >>a X -> -1 // Do not return Op0 because it may contain undef elements if it's a vector. - if (match(Op0, m_AllOnes())) + if (Q.AllowRefinement && match(Op0, m_AllOnes())) return Constant::getAllOnesValue(Op0->getType()); // (X << A) >> A -> X @@ -2069,7 +2069,7 @@ return Op0; // X & 0 = 0 - if (match(Op1, m_Zero())) + if (Q.AllowRefinement && match(Op1, m_Zero())) return Constant::getNullValue(Op0->getType()); // X & -1 = X @@ -2077,8 +2077,8 @@ return Op0; // A & ~A = ~A & A = 0 - if (match(Op0, m_Not(m_Specific(Op1))) || - match(Op1, m_Not(m_Specific(Op0)))) + if (Q.AllowRefinement && (match(Op0, m_Not(m_Specific(Op1))) || + match(Op1, m_Not(m_Specific(Op0))))) return Constant::getNullValue(Op0->getType()); // (A | ?) & A = A @@ -2231,7 +2231,7 @@ // X | undef -> -1 // X | -1 = -1 // Do not return Op1 because it may contain undef elements if it's a vector. - if (Q.isUndefValue(Op1) || match(Op1, m_AllOnes())) + if (Q.isUndefValue(Op1) || (Q.AllowRefinement && match(Op1, m_AllOnes()))) return Constant::getAllOnesValue(Op0->getType()); // X | X = X @@ -2240,8 +2240,8 @@ return Op0; // A | ~A = ~A | A = -1 - if (match(Op0, m_Not(m_Specific(Op1))) || - match(Op1, m_Not(m_Specific(Op0)))) + if (Q.AllowRefinement && (match(Op0, m_Not(m_Specific(Op1))) || + match(Op1, m_Not(m_Specific(Op0))))) return Constant::getAllOnesValue(Op0->getType()); // (A & ?) | A = A @@ -2413,12 +2413,12 @@ return Op0; // A ^ A = 0 - if (Op0 == Op1) + if (Q.AllowRefinement && Op0 == Op1) return Constant::getNullValue(Op0->getType()); // A ^ ~A = ~A ^ A = -1 - if (match(Op0, m_Not(m_Specific(Op1))) || - match(Op1, m_Not(m_Specific(Op0)))) + if (Q.AllowRefinement && (match(Op0, m_Not(m_Specific(Op1))) || + match(Op1, m_Not(m_Specific(Op0))))) return Constant::getAllOnesValue(Op0->getType()); if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::Xor)) @@ -3437,7 +3437,7 @@ // icmp X, X -> true/false // icmp X, undef -> true/false because undef could be X. - if (LHS == RHS || Q.isUndefValue(RHS)) + if (Q.AllowRefinement && (LHS == RHS || Q.isUndefValue(RHS))) return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred)); if (Value *V = simplifyICmpOfBools(Pred, LHS, RHS, Q)) @@ -3770,7 +3770,7 @@ } // fcmp x,x -> true/false. Not all compares are foldable. - if (LHS == RHS) { + if (Q.AllowRefinement && LHS == RHS) { if (CmpInst::isTrueWhenEqual(Pred)) return getTrue(RetTy); if (CmpInst::isFalseWhenEqual(Pred)) diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -899,10 +899,13 @@ ret i32 %cond } +; This cannot be optimized to 'ret (and %x, %y)' because %y might be poison. define i32 @test57(i32 %x, i32 %y) { ; CHECK-LABEL: @test57( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: ret i32 [[AND]] +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[X]], 0 +; CHECK-NEXT: [[DOTAND:%.*]] = select i1 [[TOBOOL]], i32 0, i32 [[AND]] +; CHECK-NEXT: ret i32 [[DOTAND]] ; %and = and i32 %x, %y %tobool = icmp eq i32 %x, 0 @@ -2680,7 +2683,7 @@ define i32 @pr47322_more_poisonous_replacement(i32 %arg) { ; CHECK-LABEL: @pr47322_more_poisonous_replacement( ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ARG:%.*]], 0 -; CHECK-NEXT: [[TRAILING:%.*]] = call i32 @llvm.cttz.i32(i32 [[ARG]], i1 immarg true), [[RNG0:!range !.*]] +; CHECK-NEXT: [[TRAILING:%.*]] = call i32 @llvm.cttz.i32(i32 [[ARG]], i1 immarg true), !range [[RNG0:![0-9]+]] ; CHECK-NEXT: [[SHIFTED:%.*]] = lshr i32 [[ARG]], [[TRAILING]] ; CHECK-NEXT: [[R1_SROA_0_1:%.*]] = select i1 [[CMP]], i32 0, i32 [[SHIFTED]] ; CHECK-NEXT: ret i32 [[R1_SROA_0_1]]