Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -544,10 +544,11 @@ Value *Arg = I->getArgOperand(0); - if (Arg == V && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { + if ((Arg == V || match(Arg, m_Not(m_Specific(V)))) && + isValidAssumeForContext(I, Q.CxtI, Q.DT)) { assert(BitWidth == 1 && "assume operand is not i1?"); - KnownZero.clearAllBits(); - KnownOne.setAllBits(); + KnownZero = Arg == V ? 0 : -1; + KnownOne = Arg == V ? -1 : 0; return; } Index: test/Transforms/InstCombine/assume.ll =================================================================== --- test/Transforms/InstCombine/assume.ll +++ test/Transforms/InstCombine/assume.ll @@ -176,13 +176,13 @@ 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)