[ARM] Use lrdsb for more thumb1 loads.

Given a sextload i16, we can usually generate "ldrsh [rn. rm]". If we
don't naturally have a rn, rm addressing mode, we can either generate
"ldrh [rn, #0]; sxth" or "mov rm, #0; ldrsh [rn. rm]".

We currently generate the first, always creating a sxth. They are both
the same number of instructions, but if we generate the second then the
mov #0 will likely be CSE'd or pulled out of a loop, etc.

This adjusts the ISel patterns to do that, creating a mov instead of a
sxth.

Differential Revision: https://reviews.llvm.org/D98693
This commit is contained in:
David Green 2021-03-17 15:29:02 +00:00
parent f5963944d9
commit 402f2cae7d
4 changed files with 18 additions and 22 deletions

View File

@ -1659,19 +1659,16 @@ def : T1Pat<(post_store tGPR:$Rt, tGPR:$Rn, 4),
(tSTMIA_UPD tGPR:$Rn, tGPR:$Rt)>;
// If it's impossible to use [r,r] address mode for sextload, select to
// ldr{b|h} + sxt{b|h} instead.
def : T1Pat<(sextloadi8 t_addrmode_is1:$addr),
(tSXTB (tLDRBi t_addrmode_is1:$addr))>,
// ldsr{b|h} r, 0 instead, in a hope that the mov 0 will be more likely to be
// commoned out than a sxth.
let AddedComplexity = 10 in {
def : T1Pat<(sextloadi8 tGPR:$Rn),
(tLDRSB tGPR:$Rn, (tMOVi8 0))>,
Requires<[IsThumb, IsThumb1Only, HasV6]>;
def : T1Pat<(sextloadi8 t_addrmode_rr:$addr),
(tSXTB (tLDRBr t_addrmode_rr:$addr))>,
Requires<[IsThumb, IsThumb1Only, HasV6]>;
def : T1Pat<(sextloadi16 t_addrmode_is2:$addr),
(tSXTH (tLDRHi t_addrmode_is2:$addr))>,
Requires<[IsThumb, IsThumb1Only, HasV6]>;
def : T1Pat<(sextloadi16 t_addrmode_rr:$addr),
(tSXTH (tLDRHr t_addrmode_rr:$addr))>,
def : T1Pat<(sextloadi16 tGPR:$Rn),
(tLDRSH tGPR:$Rn, (tMOVi8 0))>,
Requires<[IsThumb, IsThumb1Only, HasV6]>;
}
def : T1Pat<(sextloadi8 t_addrmode_is1:$addr),
(tASRri (tLSLri (tLDRBi t_addrmode_is1:$addr), 24), 24)>;

View File

@ -96,8 +96,8 @@ entry:
; Immediate offset of zero
; CHECK-LABEL: ldrsb_ri_zero
; CHECK-T1: ldrb r0, [r0]
; CHECK-T1: sxtb r0, r0
; CHECK-T1: movs r1, #0
; CHECK-T1: ldrsb r0, [r0, r1]
; CHECK-T2: ldrsb.w r0, [r0]
define i32 @ldrsb_ri_zero(i8* %p) {
entry:
@ -107,8 +107,8 @@ entry:
}
; CHECK-LABEL: ldrsh_ri_zero
; CHECK-T1: ldrh r0, [r0]
; CHECK-T1: sxth r0, r0
; CHECK-T1: movs r1, #0
; CHECK-T1: ldrsh r0, [r0, r1]
; CHECK-T2: ldrsh.w r0, [r0]
define i32 @ldrsh_ri_zero(i16* %p) {
entry:

View File

@ -230,10 +230,9 @@ entry:
; THUMB1-LABEL: t9:
; THUMB1: bl f
; THUMB1: sxtb r1, r4
; THUMB1: uxtb r0, r1
; THUMB1: uxtb r0, r4
; THUMB1: cmp r0, r0
; THUMB1: adds r1, r1, #1
; THUMB1: adds r1, r4, #1
; THUMB1: mov r2, r0
; THUMB1: adds r1, r1, #1
; THUMB1: adds r2, r2, #1

View File

@ -26,8 +26,8 @@ define i32 @test3(i8* %t0) nounwind {
; V5: lsls
; V5: asrs
; V6: ldrb
; V6: sxtb
; V6: mov
; V6: ldrsb
%tmp.s = load i8, i8* %t0
%tmp1.s = sext i8 %tmp.s to i32
ret i32 %tmp1.s
@ -38,8 +38,8 @@ define i32 @test4(i16* %t0) nounwind {
; V5: lsls
; V5: asrs
; V6: ldrh
; V6: sxth
; V6: mov
; V6: ldrsh
%tmp.s = load i16, i16* %t0
%tmp1.s = sext i16 %tmp.s to i32
ret i32 %tmp1.s