aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2013-07-09 22:59:22 +0000
committerJim Grosbach <grosbach@apple.com>2013-07-09 22:59:22 +0000
commit97c37bb4d4ae5e505350091e520a1354069941e0 (patch)
treeadc2a90a1ecc0d70e7d18e0dd0031e4f519b0444
parent46e11c4c97fe1c424241e4098801456303a5c86e (diff)
downloadexternal_llvm-97c37bb4d4ae5e505350091e520a1354069941e0.zip
external_llvm-97c37bb4d4ae5e505350091e520a1354069941e0.tar.gz
external_llvm-97c37bb4d4ae5e505350091e520a1354069941e0.tar.bz2
ARM: Fix incorrect pack pattern for thumb2
Propagate the fix from r185712 to Thumb2 codegen as well. Original commit message applies here as well: A "pkhtb x, x, y asr #num" uses the lower 16 bits of "y asr #num" and packs them in the bottom half of "x". An arithmetic and logic shift are only equivalent in this context if the shift amount is 16. We would be shifting in ones into the bottom 16bits instead of zeros if "y" is negative. rdar://14338767 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185982 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td7
-rw-r--r--test/CodeGen/Thumb2/thumb2-pack.ll25
2 files changed, 30 insertions, 2 deletions
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index d71824e..ee9eaaa 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -2951,7 +2951,12 @@ def t2PKHTB : T2ThreeReg<
// Alternate cases for PKHTB where identities eliminate some nodes. Note that
// a shift amount of 0 is *not legal* here, it is PKHBT instead.
-def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
+// We also can not replace a srl (17..31) by an arithmetic shift we would use in
+// pkhtb src1, src2, asr (17..31).
+def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16:$sh)),
+ (t2PKHTB rGPR:$src1, rGPR:$src2, imm16:$sh)>,
+ Requires<[HasT2ExtractPack, IsThumb2]>;
+def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (sra rGPR:$src2, imm16_31:$sh)),
(t2PKHTB rGPR:$src1, rGPR:$src2, imm16_31:$sh)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
diff --git a/test/CodeGen/Thumb2/thumb2-pack.ll b/test/CodeGen/Thumb2/thumb2-pack.ll
index 2e8bb1d..5deae1b 100644
--- a/test/CodeGen/Thumb2/thumb2-pack.ll
+++ b/test/CodeGen/Thumb2/thumb2-pack.ll
@@ -88,10 +88,33 @@ define i32 @test7(i32 %X, i32 %Y) {
}
; CHECK: test8
-; CHECK: pkhtb r0, r0, r1, asr #22
+; CHECK-NOT: pkhtb r0, r0, r1, asr #22
+; pkhtb does an arithmetic shift, not a logical shift. Make sure we don't
+; use it for problematic cases when whether sign bits would be shifted in
+; would matter.
define i32 @test8(i32 %X, i32 %Y) {
%tmp1 = and i32 %X, -65536
%tmp3 = lshr i32 %Y, 22
%tmp57 = or i32 %tmp3, %tmp1
ret i32 %tmp57
}
+
+; CHECK: test9:
+; CHECK: pkhtb r0, r0, r1, asr #16
+define i32 @test9(i32 %src1, i32 %src2) {
+entry:
+ %tmp = and i32 %src1, -65536
+ %tmp2 = lshr i32 %src2, 16
+ %tmp3 = or i32 %tmp, %tmp2
+ ret i32 %tmp3
+}
+
+; CHECK: test10
+; CHECK: pkhtb r0, r0, r1, asr #22
+define i32 @test10(i32 %X, i32 %Y) {
+ %tmp1 = and i32 %X, -65536
+ %tmp3 = ashr i32 %Y, 22
+ %tmp57 = or i32 %tmp3, %tmp1
+ ret i32 %tmp57
+}
+