summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShuxin Yang <shuxin.llvm@gmail.com>2012-12-04 22:15:32 +0000
committerShuxin Yang <shuxin.llvm@gmail.com>2012-12-04 22:15:32 +0000
commit73285933c94a41e4e4e58364ba78763127fa4c27 (patch)
tree75a1c93140da4150dc0592efba81b3f1c7330bca
parent011aea45a9e4b39e89d6ab8068c464bbd6580622 (diff)
downloadbcm5719-llvm-73285933c94a41e4e4e58364ba78763127fa4c27.tar.gz
bcm5719-llvm-73285933c94a41e4e4e58364ba78763127fa4c27.zip
For rdar://12329730, last piece.
This change attempts to simplify (X^Y) -> X or Y in the user's context if we know that only bits from X or Y are demanded. A minimized case is provided bellow. This change will simplify "t>>16" into "var1 >>16". ============================================================= unsigned foo (unsigned val1, unsigned val2) { unsigned t = val1 ^ 1234; return (t >> 16) | t; // NOTE: t is used more than once. } ============================================================= Note that if the "t" were used only once, the expression would be finally optimized as well. However, with with this change, the optimization will take place earlier. Reviewed by Nadav, Thanks a lot! llvm-svn: 169317
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp15
-rw-r--r--llvm/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll4
-rw-r--r--llvm/test/Transforms/InstCombine/shift.ll4
-rw-r--r--llvm/test/Transforms/InstCombine/xor2.ll16
4 files changed, 34 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index c832ca5644a..08aedb3200a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -200,8 +200,21 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
if ((DemandedMask & (~LHSKnownZero) & RHSKnownOne) ==
(DemandedMask & (~LHSKnownZero)))
return I->getOperand(1);
+ } else if (I->getOpcode() == Instruction::Xor) {
+ // We can simplify (X^Y) -> X or Y in the user's context if we know that
+ // only bits from X or Y are demanded.
+
+ ComputeMaskedBits(I->getOperand(1), RHSKnownZero, RHSKnownOne, Depth+1);
+ ComputeMaskedBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth+1);
+
+ // If all of the demanded bits are known zero on one side, return the
+ // other.
+ if ((DemandedMask & RHSKnownZero) == DemandedMask)
+ return I->getOperand(0);
+ if ((DemandedMask & LHSKnownZero) == DemandedMask)
+ return I->getOperand(1);
}
-
+
// Compute the KnownZero/KnownOne bits to simplify things downstream.
ComputeMaskedBits(I, KnownZero, KnownOne, Depth);
return 0;
diff --git a/llvm/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll b/llvm/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll
index 5efad8a789f..80016219791 100644
--- a/llvm/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll
+++ b/llvm/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll
@@ -5,8 +5,8 @@
define i32 @main(i32 %argc) nounwind ssp {
entry:
%tmp3151 = trunc i32 %argc to i8
-; CHECK: %tmp3162 = shl i8 %tmp3151, 5
-; CHECK: and i8 %tmp3162, 64
+; CHECK: %0 = shl i8 %tmp3151, 5
+; CHECK: and i8 %0, 64
; CHECK-NOT: shl
; CHECK-NOT: shr
%tmp3161 = or i8 %tmp3151, -17
diff --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll
index fad0bd7ede3..32867761a3f 100644
--- a/llvm/test/Transforms/InstCombine/shift.ll
+++ b/llvm/test/Transforms/InstCombine/shift.ll
@@ -523,9 +523,9 @@ entry:
%tmp51 = xor i8 %tmp50, %tmp5
%tmp52 = and i8 %tmp51, -128
%tmp53 = lshr i8 %tmp52, 7
-; CHECK: lshr i8 %tmp51, 7
%tmp54 = mul i8 %tmp53, 16
-; CHECK: shl nuw nsw i8 %tmp53, 4
+; CHECK: %0 = shl i8 %tmp4, 2
+; CHECK: %tmp54 = and i8 %0, 16
%tmp55 = xor i8 %tmp54, %tmp51
; CHECK: ret i8 %tmp551
ret i8 %tmp55
diff --git a/llvm/test/Transforms/InstCombine/xor2.ll b/llvm/test/Transforms/InstCombine/xor2.ll
index 3c992467967..4ff3b1a4552 100644
--- a/llvm/test/Transforms/InstCombine/xor2.ll
+++ b/llvm/test/Transforms/InstCombine/xor2.ll
@@ -66,3 +66,19 @@ test5:
; CHECK: lshr i32 %val1, 8
; CHECK: ret
}
+
+; defect-1 in rdar://12329730
+; Simplify (X^Y) -> X or Y in the user's context if we know that
+; only bits from X or Y are demanded.
+; e.g. the "x ^ 1234" can be optimized into x in the context of "t >> 16".
+; Put in other word, t >> 16 -> x >> 16.
+; unsigned foo(unsigned x) { nsigned t = x ^ 1234; ; return (t >> 16) + t;}
+define i32 @test6(i32 %x) {
+ %xor = xor i32 %x, 1234
+ %shr = lshr i32 %xor, 16
+ %add = add i32 %shr, %xor
+ ret i32 %add
+; CHECK: @test6
+; CHECK: lshr i32 %x, 16
+; CHECK: ret
+}
OpenPOWER on IntegriCloud