Fixes PR23809. Without passing the context to SimplifyICmpInst, we would
use the assume to prove that the condition feeding the assume is
trivially true (see isValidAssumeForContext in ValueTracking.cpp),
causing the removal of the assume which may be useful for later
optimizations.
Details
Diff Detail
Event Timeline
I noticed InstCombine never passes the context to SimplifyICmpInst/SimplifyFCmpInst. I don't see a reason for that AFAIK, but let me know if I'm missing anything. If you think this is a right approach, I'll enhance other call sites to SimplifyICmpInst/SimplifyFCmpInst as well.
It looks like SimplifyICmpInst calls ComputeSignBit with one of the ICmpInst operands. ComputeSignBit uses safeCxtI to determine which value to use for the context: if a context isn't explicitly specified, the value being interrogated is used as the context.
ISTM that the issue is that the ComputeSignBit interface has no mechanism to say "I don't have a context". One way of fixing this issue at the API boundary is to make the CxtI in ValueTracking an Optional<const Instruction *> and make safeCxtI unconditionally use the contents of the Optional if it is inhabited with a value, even if that value is nullptr.
IIUC, your proposed solution would essentially prevent SimplifyICmpInst from leveraging any @llvm.assume because computeKnownBitsFromAssume does nothing when Q.CxtI == nullptr.
It sounds an overkill to me, because SimplifyICmpInst does want to leverage @llvm.assumes that don't use the compare instruction. For instance,
b = (a > 1); __builtin_assume(b); return a > 0;
it's desirable to replace the second compare a > 0 with true while keeping __builtin_assume(b) just in case we need __builtin_assume(b) in the future.
b = (a > 1); __builtin_assume(b); return true;
and the current patch can do this.
What the current patch prevents is SimplifyICmpInst leveraging an assume to simplify its ephemeral values (see [isEphemeralValueOf](http://llvm.org/docs/doxygen/html/ValueTracking_8cpp_source.html#l00372)). That ensures LLVM won't remove __builtin_assume(b) because __builtin_assume(b) is an ephemeral value of b.
And just to be clear, I agree with you that it's a potential issue that ComputeSignBit is unable to say "I don't have a context". But my concern is, even if we fix that issue, not passing the context instruction to SimplifyICmpInst at all in InstCombine may overkill some useful optimizations.
Btw, I noticed that SimplifyDemandedBits indeed pass UserI as the context instruction (http://llvm.org/docs/doxygen/html/InstCombineSimplifyDemanded_8cpp_source.html#l00075), which seems aligned with the approach in my patch.
pass correct context to SimplifyFCmpInst
Note that this does not yet change LLVM's behavior because LLVM does not
leverage @llvm.assume to simplify fcmp for now. But anyhow, I believe it's
moving to the right direction.