Skip to content

Commit 4186a49

Browse files
committed
[RISCV] Custom type legalize i32 loads by sign extending.
The default is to use extload which can become a zextload or sextload if it is followed by an 'and' or sext_inreg. Sometimes type legalization will introduce an 'and' from promoting something like 'srl X, C' and a sext_inreg from from a setcc. The 'and' could be freely folded with the promoted 'srl' by using srliw, but the sext_inreg can't be folded into a compare. DAG combiner will see both of these choices and may decide to fold the 'and' instead of the 'sext_inreg'. This forces the sext_inreg to become a sext.w. By picking sextload in the type legalizer we take this choice away. Looking at spec2006 compiled with Zba and Zbb this appeared to be net reduction in lines of code in the objdump disassembly output. This is similar to what we do with i32 add/sub/mul/shl in type legalization where we always emit a sext_inreg. Reviewed By: asb Differential Revision: https://reviews.llvm.org/D130397
1 parent c150242 commit 4186a49

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
179179

180180
setLoadExtAction({ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}, XLenVT,
181181
MVT::i1, Promote);
182+
// DAGCombiner can call isLoadExtLegal for types that aren't legal.
183+
setLoadExtAction({ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}, MVT::i32,
184+
MVT::i1, Promote);
182185

183186
// TODO: add all necessary setOperationAction calls.
184187
setOperationAction(ISD::DYNAMIC_STACKALLOC, XLenVT, Expand);
@@ -210,6 +213,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
210213
if (Subtarget.is64Bit()) {
211214
setOperationAction(ISD::EH_DWARF_CFA, MVT::i64, Custom);
212215

216+
setOperationAction(ISD::LOAD, MVT::i32, Custom);
217+
213218
setOperationAction({ISD::ADD, ISD::SUB, ISD::SHL, ISD::SRA, ISD::SRL},
214219
MVT::i32, Custom);
215220

@@ -7087,6 +7092,22 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
70877092
Results.push_back(RCW.getValue(2));
70887093
break;
70897094
}
7095+
case ISD::LOAD: {
7096+
if (!ISD::isNON_EXTLoad(N))
7097+
return;
7098+
7099+
// Use a SEXTLOAD instead of the default EXTLOAD. Similar to the
7100+
// sext_inreg we emit for ADD/SUB/MUL/SLLI.
7101+
LoadSDNode *Ld = cast<LoadSDNode>(N);
7102+
7103+
SDLoc dl(N);
7104+
SDValue Res = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Ld->getChain(),
7105+
Ld->getBasePtr(), Ld->getMemoryVT(),
7106+
Ld->getMemOperand());
7107+
Results.push_back(DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Res));
7108+
Results.push_back(Res.getValue(1));
7109+
return;
7110+
}
70907111
case ISD::MUL: {
70917112
unsigned Size = N->getSimpleValueType(0).getSizeInBits();
70927113
unsigned XLen = Subtarget.getXLen();

llvm/test/CodeGen/RISCV/sextw-removal.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,10 @@ bb7: ; preds = %bb2
6565

6666
declare signext i32 @bar(i32 signext)
6767

68-
; The load here will be an anyext load in isel and sext.w will be emitted for
69-
; the ret. Make sure we can look through logic ops to prove the sext.w is
70-
; unnecessary.
68+
; The load here was previously an aext load, but this has since been changed
69+
; to a signext load allowing us to remove a sext.w before isel. Thus we get
70+
; the same result with or without the sext.w removal pass.
71+
; Test has been left for coverage purposes.
7172
define signext i32 @test2(i32* %p, i32 signext %b) nounwind {
7273
; RV64I-LABEL: test2:
7374
; RV64I: # %bb.0:
@@ -92,7 +93,6 @@ define signext i32 @test2(i32* %p, i32 signext %b) nounwind {
9293
; NOREMOVAL-NEXT: li a2, -2
9394
; NOREMOVAL-NEXT: rolw a1, a2, a1
9495
; NOREMOVAL-NEXT: and a0, a1, a0
95-
; NOREMOVAL-NEXT: sext.w a0, a0
9696
; NOREMOVAL-NEXT: ret
9797
%a = load i32, i32* %p
9898
%shl = shl i32 1, %b
@@ -125,7 +125,6 @@ define signext i32 @test3(i32* %p, i32 signext %b) nounwind {
125125
; NOREMOVAL-NEXT: li a2, -2
126126
; NOREMOVAL-NEXT: rolw a1, a2, a1
127127
; NOREMOVAL-NEXT: or a0, a1, a0
128-
; NOREMOVAL-NEXT: sext.w a0, a0
129128
; NOREMOVAL-NEXT: ret
130129
%a = load i32, i32* %p
131130
%shl = shl i32 1, %b
@@ -158,7 +157,6 @@ define signext i32 @test4(i32* %p, i32 signext %b) nounwind {
158157
; NOREMOVAL-NEXT: li a2, 1
159158
; NOREMOVAL-NEXT: sllw a1, a2, a1
160159
; NOREMOVAL-NEXT: xnor a0, a1, a0
161-
; NOREMOVAL-NEXT: sext.w a0, a0
162160
; NOREMOVAL-NEXT: ret
163161
%a = load i32, i32* %p
164162
%shl = shl i32 1, %b

llvm/test/CodeGen/RISCV/vec3-setcc-crash.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ define void @vec3_setcc_crash(<3 x i8>* %in, <3 x i8>* %out) {
4646
;
4747
; RV64-LABEL: vec3_setcc_crash:
4848
; RV64: # %bb.0:
49-
; RV64-NEXT: lwu a0, 0(a0)
49+
; RV64-NEXT: lw a0, 0(a0)
5050
; RV64-NEXT: slli a2, a0, 40
5151
; RV64-NEXT: slli a3, a0, 56
5252
; RV64-NEXT: slli a4, a0, 48
@@ -73,7 +73,7 @@ define void @vec3_setcc_crash(<3 x i8>* %in, <3 x i8>* %out) {
7373
; RV64-NEXT: li a0, 0
7474
; RV64-NEXT: j .LBB0_8
7575
; RV64-NEXT: .LBB0_7:
76-
; RV64-NEXT: srli a0, a0, 16
76+
; RV64-NEXT: srliw a0, a0, 16
7777
; RV64-NEXT: .LBB0_8:
7878
; RV64-NEXT: sb a0, 2(a1)
7979
; RV64-NEXT: sh a2, 0(a1)

0 commit comments

Comments
 (0)