Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -3816,6 +3816,9 @@ case Instruction::Trunc: case Instruction::BitCast: case Instruction::AddrSpaceCast: + case Instruction::Mul: + case Instruction::Shl: + case Instruction::GetElementPtr: // These operations all propagate poison unconditionally. Note that poison // is not any particular value, so xor or subtraction of poison with // itself still yields poison, not zero. @@ -3827,60 +3830,11 @@ // multiple output bits. A replicated poison bit is still poison. return true; - case Instruction::Shl: { - // Left shift *by* a poison value is poison. The number of - // positions to shift is unsigned, so no negative values are - // possible there. Left shift by zero places preserves poison. So - // it only remains to consider left shift of poison by a positive - // number of places. - // - // A left shift by a positive number of places leaves the lowest order bit - // non-poisoned. However, if such a shift has a no-wrap flag, then we can - // make the poison operand violate that flag, yielding a fresh full-poison - // value. - auto *OBO = cast(I); - return OBO->hasNoUnsignedWrap() || OBO->hasNoSignedWrap(); - } - - case Instruction::Mul: { - // A multiplication by zero yields a non-poison zero result, so we need to - // rule out zero as an operand. Conservatively, multiplication by a - // non-zero constant is not multiplication by zero. - // - // Multiplication by a non-zero constant can leave some bits - // non-poisoned. For example, a multiplication by 2 leaves the lowest - // order bit unpoisoned. So we need to consider that. - // - // Multiplication by 1 preserves poison. If the multiplication has a - // no-wrap flag, then we can make the poison operand violate that flag - // when multiplied by any integer other than 0 and 1. - auto *OBO = cast(I); - if (OBO->hasNoUnsignedWrap() || OBO->hasNoSignedWrap()) { - for (Value *V : OBO->operands()) { - if (auto *CI = dyn_cast(V)) { - // A ConstantInt cannot yield poison, so we can assume that it is - // the other operand that is poison. - return !CI->isZero(); - } - } - } - return false; - } - case Instruction::ICmp: // Comparing poison with any value yields poison. This is why, for // instance, x s< (x +nsw 1) can be folded to true. return true; - case Instruction::GetElementPtr: - // A GEP implicitly represents a sequence of additions, subtractions, - // truncations, sign extensions and multiplications. The multiplications - // are by the non-zero sizes of some set of types, so we do not have to be - // concerned with multiplication by zero. If the GEP is in-bounds, then - // these operations are implicitly no-signed-wrap so poison is propagated - // by the arguments above for Add, Sub, Trunc, SExt and Mul. - return cast(I)->isInBounds(); - default: return false; } Index: test/Analysis/Delinearization/a.ll =================================================================== --- test/Analysis/Delinearization/a.ll +++ test/Analysis/Delinearization/a.ll @@ -10,7 +10,7 @@ ; AddRec: {{{(28 + (4 * (-4 + (3 * %m)) * %o) + %A),+,(8 * %m * %o)}<%for.i>,+,(12 * %o)}<%for.j>,+,20}<%for.k> ; CHECK: Base offset: %A ; CHECK: ArrayDecl[UnknownSize][%m][%o] with elements of 4 bytes. -; CHECK: ArrayRef[{3,+,2}<%for.i>][{-4,+,3}<%for.j>][{7,+,5}<%for.k>] +; CHECK: ArrayRef[{3,+,2}<%for.i>][{-4,+,3}<%for.j>][{7,+,5}<%for.k>] define void @foo(i64 %n, i64 %m, i64 %o, i32* nocapture %A) #0 { entry: Index: test/Analysis/Delinearization/iv_times_constant_in_subscript.ll =================================================================== --- test/Analysis/Delinearization/iv_times_constant_in_subscript.ll +++ test/Analysis/Delinearization/iv_times_constant_in_subscript.ll @@ -11,7 +11,7 @@ ; AddRec: {{((%m * %b * 8) + %A),+,(2 * %m * 8)}<%for.i>,+,(2 * 8)}<%for.j> ; CHECK: Base offset: %A ; CHECK: ArrayDecl[UnknownSize][%m] with elements of 8 bytes. -; CHECK: ArrayRef[{%b,+,2}<%for.i>][{0,+,2}<%for.j>] +; CHECK: ArrayRef[{%b,+,2}<%for.i>][{0,+,2}<%for.j>] define void @foo(i64 %n, i64 %m, i64 %b, double* %A) { Index: test/Analysis/ScalarEvolution/flags-from-poison.ll =================================================================== --- test/Analysis/ScalarEvolution/flags-from-poison.ll +++ test/Analysis/ScalarEvolution/flags-from-poison.ll @@ -272,9 +272,8 @@ ret void } -; Without inbounds, GEP does not propagate poison in the very -; conservative approach used here. -define void @test-add-no-inbounds(float* %input, i32 %offset, i32 %numIterations) { +; Any poison input makes getelementptr produce poison +define void @test-gep-propagates-poison(float* %input, i32 %offset, i32 %numIterations) { ; CHECK-LABEL: @test-add-no-inbounds entry: br label %loop @@ -282,7 +281,7 @@ %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] ; CHECK: %index32 = -; CHECK: --> {%offset,+,1} +; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %ptr = getelementptr float, float* %input, i32 %index32 @@ -317,17 +316,16 @@ ret void } -; Multiplication by a non-constant should not propagate poison in the -; very conservative approach used here. -define void @test-add-mul-no-propagation(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-mul-no-propagation +; Any poison input to multiplication propages poison. +define void @test-mul-propagates-poison(float* %input, i32 %offset, i32 %numIterations) { +; CHECK-LABEL: @test-mul-propagates-poison entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] ; CHECK: %index32 = -; CHECK: --> {%offset,+,1} +; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %indexmul = mul nsw i32 %index32, %offset @@ -340,17 +338,15 @@ ret void } -; Multiplication by a non-zero constant does not propagate poison -; without a no-wrap flag. -define void @test-add-mul-no-propagation2(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-mul-no-propagation2 +define void @test-mul-propagates-poison-2(float* %input, i32 %offset, i32 %numIterations) { +; CHECK-LABEL: @test-mul-propagates-poison-2 entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] ; CHECK: %index32 = -; CHECK: --> {%offset,+,1} +; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %indexmul = mul i32 %index32, 2