Skip to content

Commit 314dbde

Browse files
committed
[DAGCombiner][ARM][RISCV] Teach ShrinkLoadReplaceStoreWithStore to use truncstore.
The VT we want to shrink to may not be legal especially after type legalization. Fixes PR56110. Reviewed By: RKSimon Differential Revision: https://reviews.llvm.org/D128135
1 parent 8c58993 commit 314dbde

File tree

3 files changed

+65
-43
lines changed

3 files changed

+65
-43
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17369,11 +17369,19 @@ ShrinkLoadReplaceStoreWithStore(const std::pair<unsigned, unsigned> &MaskInfo,
1736917369

1737017370
// Check that it is legal on the target to do this. It is legal if the new
1737117371
// VT we're shrinking to (i8/i16/i32) is legal or we're still before type
17372-
// legalization (and the target doesn't explicitly think this is a bad idea).
17372+
// legalization. If the source type is legal, but the store type isn't, see
17373+
// if we can use a truncating store.
1737317374
MVT VT = MVT::getIntegerVT(NumBytes * 8);
1737417375
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
17375-
if (!DC->isTypeLegal(VT))
17376+
bool UseTruncStore;
17377+
if (DC->isTypeLegal(VT))
17378+
UseTruncStore = false;
17379+
else if (TLI.isTypeLegal(IVal.getValueType()) &&
17380+
TLI.isTruncStoreLegal(IVal.getValueType(), VT))
17381+
UseTruncStore = true;
17382+
else
1737617383
return SDValue();
17384+
// Check that the target doesn't think this is a bad idea.
1737717385
if (St->getMemOperand() &&
1737817386
!TLI.allowsMemoryAccess(*DAG.getContext(), DAG.getDataLayout(), VT,
1737917387
*St->getMemOperand()))
@@ -17401,10 +17409,15 @@ ShrinkLoadReplaceStoreWithStore(const std::pair<unsigned, unsigned> &MaskInfo,
1740117409
Ptr = DAG.getMemBasePlusOffset(Ptr, TypeSize::Fixed(StOffset), DL);
1740217410
}
1740317411

17412+
++OpsNarrowed;
17413+
if (UseTruncStore)
17414+
return DAG.getTruncStore(St->getChain(), SDLoc(St), IVal, Ptr,
17415+
St->getPointerInfo().getWithOffset(StOffset),
17416+
VT, St->getOriginalAlign());
17417+
1740417418
// Truncate down to the new size.
1740517419
IVal = DAG.getNode(ISD::TRUNCATE, SDLoc(IVal), VT, IVal);
1740617420

17407-
++OpsNarrowed;
1740817421
return DAG
1740917422
.getStore(St->getChain(), SDLoc(St), IVal, Ptr,
1741017423
St->getPointerInfo().getWithOffset(StOffset),

llvm/test/CodeGen/ARM/illegal-bitfield-loadstore.ll

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,16 @@ define void @i56_or(i56* %a) {
9090
;
9191
; BE-LABEL: i56_or:
9292
; BE: @ %bb.0:
93-
; BE-NEXT: mov r1, r0
94-
; BE-NEXT: ldr r12, [r0]
95-
; BE-NEXT: ldrh r2, [r1, #4]!
96-
; BE-NEXT: ldrb r3, [r1, #2]
93+
; BE-NEXT: ldr r1, [r0]
94+
; BE-NEXT: strb r1, [r0, #3]
95+
; BE-NEXT: ldrh r2, [r0, #4]!
96+
; BE-NEXT: ldrb r3, [r0, #2]
9797
; BE-NEXT: orr r2, r3, r2, lsl #8
98-
; BE-NEXT: orr r2, r2, r12, lsl #24
99-
; BE-NEXT: orr r2, r2, #384
100-
; BE-NEXT: strb r2, [r1, #2]
101-
; BE-NEXT: lsr r3, r2, #8
102-
; BE-NEXT: strh r3, [r1]
103-
; BE-NEXT: bic r1, r12, #255
104-
; BE-NEXT: orr r1, r1, r2, lsr #24
105-
; BE-NEXT: str r1, [r0]
98+
; BE-NEXT: orr r1, r2, r1, lsl #24
99+
; BE-NEXT: orr r1, r1, #384
100+
; BE-NEXT: strb r1, [r0, #2]
101+
; BE-NEXT: lsr r1, r1, #8
102+
; BE-NEXT: strh r1, [r0]
106103
; BE-NEXT: mov pc, lr
107104
%aa = load i56, i56* %a
108105
%b = or i56 %aa, 384
@@ -121,20 +118,17 @@ define void @i56_and_or(i56* %a) {
121118
;
122119
; BE-LABEL: i56_and_or:
123120
; BE: @ %bb.0:
124-
; BE-NEXT: mov r1, r0
121+
; BE-NEXT: ldr r1, [r0]
125122
; BE-NEXT: mov r2, #128
126-
; BE-NEXT: ldrh r12, [r1, #4]!
127-
; BE-NEXT: ldrb r3, [r1, #2]
128-
; BE-NEXT: strb r2, [r1, #2]
123+
; BE-NEXT: strb r1, [r0, #3]
124+
; BE-NEXT: ldrh r12, [r0, #4]!
125+
; BE-NEXT: ldrb r3, [r0, #2]
126+
; BE-NEXT: strb r2, [r0, #2]
129127
; BE-NEXT: orr r2, r3, r12, lsl #8
130-
; BE-NEXT: ldr r12, [r0]
131-
; BE-NEXT: orr r2, r2, r12, lsl #24
132-
; BE-NEXT: orr r2, r2, #384
133-
; BE-NEXT: lsr r3, r2, #8
134-
; BE-NEXT: strh r3, [r1]
135-
; BE-NEXT: bic r1, r12, #255
136-
; BE-NEXT: orr r1, r1, r2, lsr #24
137-
; BE-NEXT: str r1, [r0]
128+
; BE-NEXT: orr r1, r2, r1, lsl #24
129+
; BE-NEXT: orr r1, r1, #384
130+
; BE-NEXT: lsr r1, r1, #8
131+
; BE-NEXT: strh r1, [r0]
138132
; BE-NEXT: mov pc, lr
139133

140134
%b = load i56, i56* %a, align 1
@@ -155,22 +149,16 @@ define void @i56_insert_bit(i56* %a, i1 zeroext %bit) {
155149
;
156150
; BE-LABEL: i56_insert_bit:
157151
; BE: @ %bb.0:
158-
; BE-NEXT: .save {r11, lr}
159-
; BE-NEXT: push {r11, lr}
160-
; BE-NEXT: mov r2, r0
161-
; BE-NEXT: ldr lr, [r0]
162-
; BE-NEXT: ldrh r12, [r2, #4]!
163-
; BE-NEXT: ldrb r3, [r2, #2]
164-
; BE-NEXT: orr r12, r3, r12, lsl #8
165-
; BE-NEXT: orr r3, r12, lr, lsl #24
166-
; BE-NEXT: bic r3, r3, #8192
167-
; BE-NEXT: orr r1, r3, r1, lsl #13
168-
; BE-NEXT: lsr r3, r1, #8
169-
; BE-NEXT: strh r3, [r2]
170-
; BE-NEXT: bic r2, lr, #255
171-
; BE-NEXT: orr r1, r2, r1, lsr #24
172-
; BE-NEXT: str r1, [r0]
173-
; BE-NEXT: pop {r11, lr}
152+
; BE-NEXT: ldr r2, [r0]
153+
; BE-NEXT: strb r2, [r0, #3]
154+
; BE-NEXT: ldrh r12, [r0, #4]!
155+
; BE-NEXT: ldrb r3, [r0, #2]
156+
; BE-NEXT: orr r3, r3, r12, lsl #8
157+
; BE-NEXT: orr r2, r3, r2, lsl #24
158+
; BE-NEXT: bic r2, r2, #8192
159+
; BE-NEXT: orr r1, r2, r1, lsl #13
160+
; BE-NEXT: lsr r1, r1, #8
161+
; BE-NEXT: strh r1, [r0]
174162
; BE-NEXT: mov pc, lr
175163
%extbit = zext i1 %bit to i56
176164
%b = load i56, i56* %a, align 1

llvm/test/CodeGen/RISCV/pr56110.ll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=riscv32 | FileCheck %s
3+
; RUN: llc < %s -mtriple=riscv32 -mattr=+unaligned-scalar-mem | FileCheck %s
4+
5+
define void @foo_set(ptr nocapture noundef %a, i32 noundef %v) {
6+
; CHECK-LABEL: foo_set:
7+
; CHECK: # %bb.0: # %entry
8+
; CHECK-NEXT: srli a2, a1, 8
9+
; CHECK-NEXT: sb a1, 3(a0)
10+
; CHECK-NEXT: sb a2, 4(a0)
11+
; CHECK-NEXT: ret
12+
entry:
13+
%bf.load = load i96, ptr %a, align 1
14+
%0 = and i32 %v, 65535
15+
%bf.value = zext i32 %0 to i96
16+
%bf.shl = shl nuw nsw i96 %bf.value, 24
17+
%bf.clear = and i96 %bf.load, -1099494850561
18+
%bf.set = or i96 %bf.clear, %bf.shl
19+
store i96 %bf.set, ptr %a, align 1
20+
ret void
21+
}

0 commit comments

Comments
 (0)