diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2014-01-09 10:56:42 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2014-01-09 10:56:42 +0000 |
commit | acb31a245ceef3510f37163e31c0097b0d63cb8f (patch) | |
tree | 697f6ad55b0ab7c3562eb364d7857e3af5d7e956 /test/CodeGen/SystemZ | |
parent | 2984497cc1feb475d8ec97c9924dcc9bd02e0de0 (diff) | |
download | llvm-acb31a245ceef3510f37163e31c0097b0d63cb8f.tar.gz llvm-acb31a245ceef3510f37163e31c0097b0d63cb8f.tar.bz2 llvm-acb31a245ceef3510f37163e31c0097b0d63cb8f.tar.xz |
Handle masked rotate amounts
At the moment we expect rotates to have the form:
(or (shl X, Y), (shr X, Z))
where Y == bitsize(X) - Z or Z == bitsize(X) - Y. This form means that
the (or ...) is undefined for Y == 0 or Z == 0. This undefinedness can
be avoided by using Y == (C * bitsize(X) - Z) & (bitsize(X) - 1) or
Z == (C * bitsize(X) - Y) & (bitsize(X) - 1) for any integer C
(including 0, the most natural choice).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198861 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/SystemZ')
-rw-r--r-- | test/CodeGen/SystemZ/shift-04.ll | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/test/CodeGen/SystemZ/shift-04.ll b/test/CodeGen/SystemZ/shift-04.ll index 0cd32391ed..de2d74f27f 100644 --- a/test/CodeGen/SystemZ/shift-04.ll +++ b/test/CodeGen/SystemZ/shift-04.ll @@ -216,3 +216,75 @@ define i32 @f16(i32 %a, i64 %amt) { %or = or i32 %parta, %partb ret i32 %or } + +; Check cases where (-x & 31) is used instead of 32 - x. +define i32 @f17(i32 %x, i32 %y) { +; CHECK-LABEL: f17: +; CHECK: rll %r2, %r2, 0(%r3) +; CHECK: br %r14 +entry: + %shl = shl i32 %x, %y + %sub = sub i32 0, %y + %and = and i32 %sub, 31 + %shr = lshr i32 %x, %and + %or = or i32 %shr, %shl + ret i32 %or +} + +; ...and again with ((32 - x) & 31). +define i32 @f18(i32 %x, i32 %y) { +; CHECK-LABEL: f18: +; CHECK: rll %r2, %r2, 0(%r3) +; CHECK: br %r14 +entry: + %shl = shl i32 %x, %y + %sub = sub i32 32, %y + %and = and i32 %sub, 31 + %shr = lshr i32 %x, %and + %or = or i32 %shr, %shl + ret i32 %or +} + +; This is not a rotation. +define i32 @f19(i32 %x, i32 %y) { +; CHECK-LABEL: f19: +; CHECK-NOT: rll +; CHECK: br %r14 +entry: + %shl = shl i32 %x, %y + %sub = sub i32 16, %y + %and = and i32 %sub, 31 + %shr = lshr i32 %x, %and + %or = or i32 %shr, %shl + ret i32 %or +} + +; Repeat f17 with an addition on the shift count. +define i32 @f20(i32 %x, i32 %y) { +; CHECK-LABEL: f20: +; CHECK: rll %r2, %r2, 199(%r3) +; CHECK: br %r14 +entry: + %add = add i32 %y, 199 + %shl = shl i32 %x, %add + %sub = sub i32 0, %add + %and = and i32 %sub, 31 + %shr = lshr i32 %x, %and + %or = or i32 %shr, %shl + ret i32 %or +} + +; ...and again with the InstCombine version. +define i32 @f21(i32 %x, i32 %y) { +; CHECK-LABEL: f21: +; CHECK: rll %r2, %r2, 199(%r3) +; CHECK: br %r14 +entry: + %add = add i32 %y, 199 + %shl = shl i32 %x, %add + %sub = sub i32 -199, %y + %and = and i32 %sub, 31 + %shr = lshr i32 %x, %and + %or = or i32 %shr, %shl + ret i32 %or +} |