diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-04-19 16:46:26 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-04-19 16:46:26 +0000 |
commit | 0d5fcae6cd7b96a5a483d6179d2908517970169c (patch) | |
tree | 91dbfb1fe1fc44579921c52f22b9580ad7b5cf6c /test/Transforms/InstCombine/shift.ll | |
parent | 057a4b40a65692ea54e0a00cb6ea27d0855be51f (diff) | |
download | external_llvm-0d5fcae6cd7b96a5a483d6179d2908517970169c.zip external_llvm-0d5fcae6cd7b96a5a483d6179d2908517970169c.tar.gz external_llvm-0d5fcae6cd7b96a5a483d6179d2908517970169c.tar.bz2 |
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/InstCombine/shift.ll')
-rw-r--r-- | test/Transforms/InstCombine/shift.ll | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll index 52310e3..25e708b 100644 --- a/test/Transforms/InstCombine/shift.ll +++ b/test/Transforms/InstCombine/shift.ll @@ -65,8 +65,17 @@ define i32 @test6(i32 %A) { ; CHECK: @test6 ; CHECK-NEXT: mul i32 %A, 6 ; CHECK-NEXT: ret i32 - %B = shl i32 %A, 1 ;; convert to an mul instruction - %C = mul i32 %B, 3 + %B = shl i32 %A, 1 ;; convert to an mul instruction + %C = mul i32 %B, 3 + ret i32 %C +} + +define i32 @test6a(i32 %A) { +; CHECK: @test6a +; CHECK-NEXT: mul i32 %A, 6 +; CHECK-NEXT: ret i32 + %B = mul i32 %A, 3 + %C = shl i32 %B, 1 ;; convert to an mul instruction ret i32 %C } @@ -97,7 +106,9 @@ define i8 @test9(i8 %A) { ret i8 %C } +;; This transformation is deferred to DAGCombine: ;; (A >> 7) << 7 === A & 128 +;; The shl may be valuable to scalar evolution. define i8 @test10(i8 %A) { ; CHECK: @test10 ; CHECK-NEXT: and i8 %A, -128 @@ -107,11 +118,21 @@ define i8 @test10(i8 %A) { ret i8 %C } +;; Allow the simplification when the lshr shift is exact. +define i8 @test10a(i8 %A) { +; CHECK: @test10a +; CHECK-NEXT: ret i8 %A + %B = lshr exact i8 %A, 7 + %C = shl i8 %B, 7 + ret i8 %C +} + +;; This transformation is deferred to DAGCombine: ;; (A >> 3) << 4 === (A & 0x1F) << 1 +;; The shl may be valuable to scalar evolution. define i8 @test11(i8 %A) { ; CHECK: @test11 -; CHECK-NEXT: mul i8 %A, 6 -; CHECK-NEXT: and i8 +; CHECK: shl i8 ; CHECK-NEXT: ret i8 %a = mul i8 %A, 3 ; <i8> [#uses=1] %B = lshr i8 %a, 3 ; <i8> [#uses=1] @@ -119,6 +140,18 @@ define i8 @test11(i8 %A) { ret i8 %C } +;; Allow the simplification in InstCombine when the lshr shift is exact. +define i8 @test11a(i8 %A) { +; CHECK: @test11a +; CHECK-NEXT: mul i8 %A, 6 +; CHECK-NEXT: ret i8 + %a = mul i8 %A, 3 + %B = lshr exact i8 %a, 3 + %C = shl i8 %B, 4 + ret i8 %C +} + +;; This is deferred to DAGCombine unless %B is single-use. ;; (A >> 8) << 8 === A & -256 define i32 @test12(i32 %A) { ; CHECK: @test12 @@ -129,11 +162,12 @@ define i32 @test12(i32 %A) { ret i32 %C } +;; This transformation is deferred to DAGCombine: ;; (A >> 3) << 4 === (A & -8) * 2 +;; The shl may be valuable to scalar evolution. define i8 @test13(i8 %A) { ; CHECK: @test13 -; CHECK-NEXT: mul i8 %A, 6 -; CHECK-NEXT: and i8 +; CHECK: shl i8 ; CHECK-NEXT: ret i8 %a = mul i8 %A, 3 ; <i8> [#uses=1] %B = ashr i8 %a, 3 ; <i8> [#uses=1] @@ -141,6 +175,16 @@ define i8 @test13(i8 %A) { ret i8 %C } +define i8 @test13a(i8 %A) { +; CHECK: @test13a +; CHECK-NEXT: mul i8 %A, 6 +; CHECK-NEXT: ret i8 + %a = mul i8 %A, 3 + %B = ashr exact i8 %a, 3 + %C = shl i8 %B, 4 + ret i8 %C +} + ;; D = ((B | 1234) << 4) === ((B << 4)|(1234 << 4) define i32 @test14(i32 %A) { ; CHECK: @test14 @@ -477,10 +521,11 @@ entry: %tmp49 = lshr i8 %tmp48, 5 %tmp50 = mul i8 %tmp49, 64 %tmp51 = xor i8 %tmp50, %tmp5 -; CHECK: and i8 %0, 16 %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 %tmp55 = xor i8 %tmp54, %tmp51 ; CHECK: ret i8 %tmp551 ret i8 %tmp55 |