diff options
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 7 | ||||
-rw-r--r-- | llvm/test/CodeGen/Thumb2/thumb2-pack.ll | 25 |
2 files changed, 30 insertions, 2 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index d71824e3c65..ee9eaaab319 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/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/llvm/test/CodeGen/Thumb2/thumb2-pack.ll b/llvm/test/CodeGen/Thumb2/thumb2-pack.ll index 2e8bb1d6093..5deae1bf8f2 100644 --- a/llvm/test/CodeGen/Thumb2/thumb2-pack.ll +++ b/llvm/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 +} + |