[PATCH] PR19711: use computeKnownBits to simplify (in)equality comparisons
Jay Foad
jay.foad at gmail.com
Tue May 20 05:08:16 PDT 2014
PR19711: Souper (https://github.com/google/souper/) discovered that we
don't simplify this comparison to false:
%mul = mul nsw i32 %0, -2
%cmp = icmp eq i32 %mul, 1
Fix this by calling computeKnownBits to see if any bits are known to be 0
in one operand and 1 in the other, in which case the operands can't be
equal.
I was a bit surprised that before this patch, there were no calls from
InstructionSimplify.cpp to computeKnownBits. Is this the right approach? OK
to commit?
The tweak to align-2d-gep.ll just avoids an unintended simplification,
where we could prove that %indvar.next was always even so could never equal
557.
Thanks,
Jay.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140520/9cba2ed8/attachment.html>
-------------- next part --------------
Index: lib/Analysis/InstructionSimplify.cpp
===================================================================
--- lib/Analysis/InstructionSimplify.cpp (revision 209203)
+++ lib/Analysis/InstructionSimplify.cpp (working copy)
@@ -2652,6 +2652,21 @@
if (Value *V = ThreadCmpOverPHI(Pred, LHS, RHS, Q, MaxRecurse))
return V;
+ // Try using bitwise analysis to prove that the operands are unequal.
+ if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) {
+ unsigned BitWidth = OpTy->getScalarSizeInBits();
+
+ APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
+ computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, Q.DL, 0);
+
+ APInt RHSKnownZero(BitWidth, 0), RHSKnownOne(BitWidth, 0);
+ computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, Q.DL, 0);
+
+ if ((LHSKnownZero & RHSKnownOne) != 0 || (LHSKnownOne & RHSKnownZero) != 0)
+ // The operands differ in one or more bit positions.
+ return Pred == CmpInst::ICMP_NE ? getTrue(ITy) : getFalse(ITy);
+ }
+
return nullptr;
}
Index: test/Transforms/InstCombine/align-2d-gep.ll
===================================================================
--- test/Transforms/InstCombine/align-2d-gep.ll (revision 209203)
+++ test/Transforms/InstCombine/align-2d-gep.ll (working copy)
@@ -31,7 +31,7 @@
store <2 x double><double 0.0, double 0.0>, <2 x double>* %r, align 8
%indvar.next = add i64 %j, 2
- %exitcond = icmp eq i64 %indvar.next, 557
+ %exitcond = icmp eq i64 %indvar.next, 556
br i1 %exitcond, label %bb11, label %bb1
bb11:
Index: test/Transforms/InstCombine/icmp.ll
===================================================================
--- test/Transforms/InstCombine/icmp.ll (revision 209203)
+++ test/Transforms/InstCombine/icmp.ll (working copy)
@@ -1365,3 +1365,11 @@
%2 = icmp slt i32 %1, -10
ret i1 %2
}
+
+; CHECK-LABEL: @icmp_mul_neg2
+; CHECK: ret i1 false
+define i1 @icmp_mul_neg2(i32 %a) nounwind {
+ %mul = mul i32 %a, -2
+ %cmp = icmp eq i32 %mul, 1
+ ret i1 %cmp
+}
More information about the llvm-commits
mailing list