diff options
-rw-r--r-- | llvm/lib/Analysis/AssumptionCache.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 7 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/assume.ll | 4 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/select.ll | 5 |
4 files changed, 16 insertions, 8 deletions
diff --git a/llvm/lib/Analysis/AssumptionCache.cpp b/llvm/lib/Analysis/AssumptionCache.cpp index 5851594700a..4e287e5f6bc 100644 --- a/llvm/lib/Analysis/AssumptionCache.cpp +++ b/llvm/lib/Analysis/AssumptionCache.cpp @@ -47,9 +47,11 @@ void AssumptionCache::updateAffectedValues(CallInst *CI) { } else if (auto *I = dyn_cast<Instruction>(V)) { Affected.push_back(I); - if (I->getOpcode() == Instruction::BitCast || - I->getOpcode() == Instruction::PtrToInt) { - auto *Op = I->getOperand(0); + // Peek through unary operators to find the source of the condition. + Value *Op; + if (match(I, m_BitCast(m_Value(Op))) || + match(I, m_PtrToInt(m_Value(Op))) || + match(I, m_Not(m_Value(Op)))) { if (isa<Instruction>(Op) || isa<Argument>(Op)) Affected.push_back(Op); } diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index d926b3864de..00536235287 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -553,6 +553,13 @@ static void computeKnownBitsFromAssume(const Value *V, APInt &KnownZero, KnownOne.setAllBits(); return; } + if (match(Arg, m_Not(m_Specific(V))) && + isValidAssumeForContext(I, Q.CxtI, Q.DT)) { + assert(BitWidth == 1 && "assume operand is not i1?"); + KnownZero.setAllBits(); + KnownOne.clearAllBits(); + return; + } // The remaining tests are all recursive, so bail out if we hit the limit. if (Depth == MaxDepth) diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll index 6e690426db9..13fa6339e85 100644 --- a/llvm/test/Transforms/InstCombine/assume.ll +++ b/llvm/test/Transforms/InstCombine/assume.ll @@ -176,13 +176,13 @@ define i32 @icmp2(i32 %a) #0 { ret i32 %lnot.ext } -; FIXME: If the 'not' of a condition is known true, then the condition must be false. +; If the 'not' of a condition is known true, then the condition must be false. define i1 @assume_not(i1 %cond) { ; CHECK-LABEL: @assume_not( ; CHECK-NEXT: [[NOTCOND:%.*]] = xor i1 [[COND:%.*]], true ; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]]) -; CHECK-NEXT: ret i1 [[COND]] +; CHECK-NEXT: ret i1 false ; %notcond = xor i1 %cond, true call void @llvm.assume(i1 %notcond) diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index f8fe2fbc1a2..fac50b2f039 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -1344,14 +1344,13 @@ define i8 @assume_cond_true(i1 %cond, i8 %x, i8 %y) { ret i8 %sel } -; FIXME: computeKnownBitsFromAssume() should understand the 'not' of an assumed condition. +; computeKnownBitsFromAssume() understands the 'not' of an assumed condition. define i8 @assume_cond_false(i1 %cond, i8 %x, i8 %y) { ; CHECK-LABEL: @assume_cond_false( ; CHECK-NEXT: [[NOTCOND:%.*]] = xor i1 %cond, true ; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]]) -; CHECK-NEXT: [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y -; CHECK-NEXT: ret i8 [[SEL]] +; CHECK-NEXT: ret i8 %y ; %notcond = xor i1 %cond, true call void @llvm.assume(i1 %notcond) |