diff options
| author | Eli Friedman <efriedma@codeaurora.org> | 2019-01-22 01:51:37 +0000 |
|---|---|---|
| committer | Eli Friedman <efriedma@codeaurora.org> | 2019-01-22 01:51:37 +0000 |
| commit | 1eaa04d682d684f7e83c263aa40e78ae8faab378 (patch) | |
| tree | 7c830e0e619839a838c8f558b3250dd6ff69f6ec /llvm/test/CodeGen/Thumb | |
| parent | 390c0e2f728e4e5feb89301eb758a67ae296d350 (diff) | |
| download | bcm5719-llvm-1eaa04d682d684f7e83c263aa40e78ae8faab378.tar.gz bcm5719-llvm-1eaa04d682d684f7e83c263aa40e78ae8faab378.zip | |
[ARM] Combine ands+lsls to lsls+lsrs for Thumb1.
This patch may seem familiar... but my previous patch handled the
equivalent lsls+and, not this case. Usually instcombine puts the
"and" after the shift, so this case doesn't come up. However, if the
shift comes out of a GEP, it won't get canonicalized by instcombine,
and DAGCombine doesn't have an equivalent transform.
This also modifies isDesirableToCommuteWithShift to suppress DAGCombine
transforms which would make the overall code worse.
I'm not really happy adding a bunch of code to handle this, but it would
probably be tricky to substantially improve the behavior of DAGCombine
here.
Differential Revision: https://reviews.llvm.org/D56032
llvm-svn: 351776
Diffstat (limited to 'llvm/test/CodeGen/Thumb')
| -rw-r--r-- | llvm/test/CodeGen/Thumb/shift-and.ll | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/Thumb/shift-and.ll b/llvm/test/CodeGen/Thumb/shift-and.ll index 3981d2c9702..b8e3416adbb 100644 --- a/llvm/test/CodeGen/Thumb/shift-and.ll +++ b/llvm/test/CodeGen/Thumb/shift-and.ll @@ -188,3 +188,73 @@ entry: %shl = shl i32 %shr, 3 ret i32 %shl } + +define i32 @test16(i32 %x) { +; CHECK-LABEL: test16: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: lsls r0, r0, #28 +; CHECK-NEXT: lsrs r0, r0, #26 +; CHECK-NEXT: bx lr +entry: + %0 = and i32 %x, 15 + %shl = shl i32 %0, 2 + ret i32 %shl +} + +define i32* @test17(i32* %p, i32 %x) { +; CHECK-LABEL: test17: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: lsls r1, r1, #28 +; CHECK-NEXT: lsrs r1, r1, #26 +; CHECK-NEXT: adds r0, r0, r1 +; CHECK-NEXT: bx lr +entry: + %0 = and i32 %x, 15 + %shl = getelementptr i32, i32* %p, i32 %0 + ret i32* %shl +} + +define i32* @test18(i32* %p, i32 %x) { +; CHECK-LABEL: test18: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: adds r1, r1, #1 +; CHECK-NEXT: lsls r1, r1, #28 +; CHECK-NEXT: lsrs r1, r1, #26 +; CHECK-NEXT: adds r0, r0, r1 +; CHECK-NEXT: bx lr +entry: + %xx = add i32 %x, 1 + %0 = and i32 %xx, 15 + %shl = getelementptr i32, i32* %p, i32 %0 + ret i32* %shl +} + +define i32* @test19(i32* %p, i32 %x) { +; CHECK-LABEL: test19: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: subs r1, r1, #1 +; CHECK-NEXT: lsls r1, r1, #28 +; CHECK-NEXT: lsrs r1, r1, #26 +; CHECK-NEXT: adds r0, r0, r1 +; CHECK-NEXT: bx lr +entry: + %xx = sub i32 %x, 1 + %0 = and i32 %xx, 15 + %shl = getelementptr i32, i32* %p, i32 %0 + ret i32* %shl +} + +define i32* @test20(i32* %p, i32 %x) { +; CHECK-LABEL: test20: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: subs r1, r1, #1 +; CHECK-NEXT: lsls r1, r1, #28 +; CHECK-NEXT: lsrs r1, r1, #26 +; CHECK-NEXT: adds r0, r0, r1 +; CHECK-NEXT: bx lr +entry: + %xx = add i32 %x, 15 + %0 = and i32 %xx, 15 + %shl = getelementptr i32, i32* %p, i32 %0 + ret i32* %shl +} |

