summaryrefslogtreecommitdiff
path: root/test/Transforms/PhaseOrdering/basic.ll
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-04-19 16:46:26 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-04-19 16:46:26 +0000
commit0d5fcae6cd7b96a5a483d6179d2908517970169c (patch)
tree91dbfb1fe1fc44579921c52f22b9580ad7b5cf6c /test/Transforms/PhaseOrdering/basic.ll
parent057a4b40a65692ea54e0a00cb6ea27d0855be51f (diff)
downloadllvm-0d5fcae6cd7b96a5a483d6179d2908517970169c.tar.gz
llvm-0d5fcae6cd7b96a5a483d6179d2908517970169c.tar.bz2
llvm-0d5fcae6cd7b96a5a483d6179d2908517970169c.tar.xz
Defer some shl transforms to DAGCombine.
The shl instruction is used to represent multiplication by a constant power of two as well as bitwise left shifts. Some InstCombine transformations would turn an shl instruction into a bit mask operation, making it difficult for later analysis passes to recognize the constsnt multiplication. Disable those shl transformations, deferring them to DAGCombine time. An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'. These transformations are deferred: (X >>? C) << C --> X & (-1 << C) (When X >> C has multiple uses) (X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) (When C2 > C1) (X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) (When C1 > C2) The corresponding exact transformations are preserved, just like div-exact + mul: (X >>?,exact C) << C --> X (X >>?,exact C1) << C2 --> X << (C2-C1) (X >>?,exact C1) << C2 --> X >>?,exact (C1-C2) The disabled transformations could also prevent the instruction selector from recognizing rotate patterns in hash functions and cryptographic primitives. I have a test case for that, but it is too fragile. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155136 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/PhaseOrdering/basic.ll')
-rw-r--r--test/Transforms/PhaseOrdering/basic.ll27
1 files changed, 27 insertions, 0 deletions
diff --git a/test/Transforms/PhaseOrdering/basic.ll b/test/Transforms/PhaseOrdering/basic.ll
index 2d52ae50df..88ebca0a9c 100644
--- a/test/Transforms/PhaseOrdering/basic.ll
+++ b/test/Transforms/PhaseOrdering/basic.ll
@@ -22,3 +22,30 @@ define void @test1() nounwind ssp {
; CHECK: @test1
; CHECK-NEXT: ret void
}
+
+; This function exposes a phase ordering problem when InstCombine is
+; turning %add into a bitmask, making it difficult to spot a 0 return value.
+;
+; It it also important that %add is expressed as a multiple of %div so scalar
+; evolution can recognize it.
+define i32 @test2(i32 %a, i32* %p) nounwind uwtable ssp {
+entry:
+ %div = udiv i32 %a, 4
+ %arrayidx = getelementptr inbounds i32* %p, i64 0
+ store i32 %div, i32* %arrayidx, align 4
+ %add = add i32 %div, %div
+ %arrayidx1 = getelementptr inbounds i32* %p, i64 1
+ store i32 %add, i32* %arrayidx1, align 4
+ %arrayidx2 = getelementptr inbounds i32* %p, i64 1
+ %0 = load i32* %arrayidx2, align 4
+ %arrayidx3 = getelementptr inbounds i32* %p, i64 0
+ %1 = load i32* %arrayidx3, align 4
+ %mul = mul i32 2, %1
+ %sub = sub i32 %0, %mul
+ ret i32 %sub
+
+; CHECK: @test2
+; CHECK: %div = lshr i32 %a, 2
+; CHECK: %add = shl nuw nsw i32 %div, 1
+; CHECK: ret i32 0
+}