Skip to content

Commit 2a21260

Browse files
toppercvitalybuka
authored andcommitted
[SelectionDAG] Use getVectorElementPointer in DAGCombiner::replaceStoreOfInsertLoad. (#74249)
This ensures we clip the index to be in bounds of the vector we are inserting into. If the index is out of bounds the results of the insert element is poison. If we don't clip the index we can write memory that was not part of the original store. Fixes #74248 #75557.
1 parent f4b5be1 commit 2a21260

File tree

4 files changed

+40
-41
lines changed

4 files changed

+40
-41
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21005,20 +21005,18 @@ SDValue DAGCombiner::replaceStoreOfInsertLoad(StoreSDNode *ST) {
2100521005
&IsFast) ||
2100621006
!IsFast)
2100721007
return SDValue();
21008-
EVT PtrVT = Ptr.getValueType();
2100921008

21010-
SDValue Offset =
21011-
DAG.getNode(ISD::MUL, DL, PtrVT, DAG.getZExtOrTrunc(Idx, DL, PtrVT),
21012-
DAG.getConstant(EltVT.getSizeInBits() / 8, DL, PtrVT));
21013-
SDValue NewPtr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, Offset);
2101421009
MachinePointerInfo PointerInfo(ST->getAddressSpace());
2101521010

2101621011
// If the offset is a known constant then try to recover the pointer
2101721012
// info
21013+
SDValue NewPtr;
2101821014
if (auto *CIdx = dyn_cast<ConstantSDNode>(Idx)) {
2101921015
unsigned COffset = CIdx->getSExtValue() * EltVT.getSizeInBits() / 8;
2102021016
NewPtr = DAG.getMemBasePlusOffset(Ptr, TypeSize::getFixed(COffset), DL);
2102121017
PointerInfo = ST->getPointerInfo().getWithOffset(COffset);
21018+
} else {
21019+
NewPtr = TLI.getVectorElementPointer(DAG, Ptr, Value.getValueType(), Idx);
2102221020
}
2102321021

2102421022
return DAG.getStore(Chain, DL, Elt, NewPtr, PointerInfo, ST->getAlign(),

llvm/test/CodeGen/Mips/msa/basic_operations.ll

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,7 @@ define void @insert_v16i8_vidx(i32 signext %a) nounwind {
18791879
; O32-NEXT: addu $1, $2, $25
18801880
; O32-NEXT: lw $2, %got(i32)($1)
18811881
; O32-NEXT: lw $2, 0($2)
1882+
; O32-NEXT: andi $2, $2, 15
18821883
; O32-NEXT: lw $1, %got(v16i8)($1)
18831884
; O32-NEXT: addu $1, $1, $2
18841885
; O32-NEXT: jr $ra
@@ -1891,6 +1892,7 @@ define void @insert_v16i8_vidx(i32 signext %a) nounwind {
18911892
; N32-NEXT: addiu $1, $1, %lo(%neg(%gp_rel(insert_v16i8_vidx)))
18921893
; N32-NEXT: lw $2, %got_disp(i32)($1)
18931894
; N32-NEXT: lw $2, 0($2)
1895+
; N32-NEXT: andi $2, $2, 15
18941896
; N32-NEXT: lw $1, %got_disp(v16i8)($1)
18951897
; N32-NEXT: addu $1, $1, $2
18961898
; N32-NEXT: jr $ra
@@ -1902,7 +1904,8 @@ define void @insert_v16i8_vidx(i32 signext %a) nounwind {
19021904
; N64-NEXT: daddu $1, $1, $25
19031905
; N64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(insert_v16i8_vidx)))
19041906
; N64-NEXT: ld $2, %got_disp(i32)($1)
1905-
; N64-NEXT: lwu $2, 0($2)
1907+
; N64-NEXT: lw $2, 0($2)
1908+
; N64-NEXT: andi $2, $2, 15
19061909
; N64-NEXT: ld $1, %got_disp(v16i8)($1)
19071910
; N64-NEXT: daddu $1, $1, $2
19081911
; N64-NEXT: jr $ra
@@ -1925,6 +1928,7 @@ define void @insert_v8i16_vidx(i32 signext %a) nounwind {
19251928
; O32-NEXT: addu $1, $2, $25
19261929
; O32-NEXT: lw $2, %got(i32)($1)
19271930
; O32-NEXT: lw $2, 0($2)
1931+
; O32-NEXT: andi $2, $2, 7
19281932
; O32-NEXT: lw $1, %got(v8i16)($1)
19291933
; O32-NEXT: lsa $1, $2, $1, 1
19301934
; O32-NEXT: jr $ra
@@ -1937,6 +1941,7 @@ define void @insert_v8i16_vidx(i32 signext %a) nounwind {
19371941
; N32-NEXT: addiu $1, $1, %lo(%neg(%gp_rel(insert_v8i16_vidx)))
19381942
; N32-NEXT: lw $2, %got_disp(i32)($1)
19391943
; N32-NEXT: lw $2, 0($2)
1944+
; N32-NEXT: andi $2, $2, 7
19401945
; N32-NEXT: lw $1, %got_disp(v8i16)($1)
19411946
; N32-NEXT: lsa $1, $2, $1, 1
19421947
; N32-NEXT: jr $ra
@@ -1948,7 +1953,8 @@ define void @insert_v8i16_vidx(i32 signext %a) nounwind {
19481953
; N64-NEXT: daddu $1, $1, $25
19491954
; N64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(insert_v8i16_vidx)))
19501955
; N64-NEXT: ld $2, %got_disp(i32)($1)
1951-
; N64-NEXT: lwu $2, 0($2)
1956+
; N64-NEXT: lw $2, 0($2)
1957+
; N64-NEXT: andi $2, $2, 7
19521958
; N64-NEXT: ld $1, %got_disp(v8i16)($1)
19531959
; N64-NEXT: dlsa $1, $2, $1, 1
19541960
; N64-NEXT: jr $ra
@@ -1971,6 +1977,7 @@ define void @insert_v4i32_vidx(i32 signext %a) nounwind {
19711977
; O32-NEXT: addu $1, $2, $25
19721978
; O32-NEXT: lw $2, %got(i32)($1)
19731979
; O32-NEXT: lw $2, 0($2)
1980+
; O32-NEXT: andi $2, $2, 3
19741981
; O32-NEXT: lw $1, %got(v4i32)($1)
19751982
; O32-NEXT: lsa $1, $2, $1, 2
19761983
; O32-NEXT: jr $ra
@@ -1983,6 +1990,7 @@ define void @insert_v4i32_vidx(i32 signext %a) nounwind {
19831990
; N32-NEXT: addiu $1, $1, %lo(%neg(%gp_rel(insert_v4i32_vidx)))
19841991
; N32-NEXT: lw $2, %got_disp(i32)($1)
19851992
; N32-NEXT: lw $2, 0($2)
1993+
; N32-NEXT: andi $2, $2, 3
19861994
; N32-NEXT: lw $1, %got_disp(v4i32)($1)
19871995
; N32-NEXT: lsa $1, $2, $1, 2
19881996
; N32-NEXT: jr $ra
@@ -1994,7 +2002,8 @@ define void @insert_v4i32_vidx(i32 signext %a) nounwind {
19942002
; N64-NEXT: daddu $1, $1, $25
19952003
; N64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(insert_v4i32_vidx)))
19962004
; N64-NEXT: ld $2, %got_disp(i32)($1)
1997-
; N64-NEXT: lwu $2, 0($2)
2005+
; N64-NEXT: lw $2, 0($2)
2006+
; N64-NEXT: andi $2, $2, 3
19982007
; N64-NEXT: ld $1, %got_disp(v4i32)($1)
19992008
; N64-NEXT: dlsa $1, $2, $1, 2
20002009
; N64-NEXT: jr $ra
@@ -2018,6 +2027,7 @@ define void @insert_v2i64_vidx(i64 signext %a) nounwind {
20182027
; O32-NEXT: addu $1, $2, $25
20192028
; O32-NEXT: lw $2, %got(i32)($1)
20202029
; O32-NEXT: lw $2, 0($2)
2030+
; O32-NEXT: andi $2, $2, 1
20212031
; O32-NEXT: lw $1, %got(v2i64)($1)
20222032
; O32-NEXT: lsa $1, $2, $1, 3
20232033
; O32-NEXT: sw $5, 4($1)
@@ -2031,6 +2041,7 @@ define void @insert_v2i64_vidx(i64 signext %a) nounwind {
20312041
; N32-NEXT: addiu $1, $1, %lo(%neg(%gp_rel(insert_v2i64_vidx)))
20322042
; N32-NEXT: lw $2, %got_disp(i32)($1)
20332043
; N32-NEXT: lw $2, 0($2)
2044+
; N32-NEXT: andi $2, $2, 1
20342045
; N32-NEXT: lw $1, %got_disp(v2i64)($1)
20352046
; N32-NEXT: lsa $1, $2, $1, 3
20362047
; N32-NEXT: jr $ra
@@ -2042,7 +2053,8 @@ define void @insert_v2i64_vidx(i64 signext %a) nounwind {
20422053
; N64-NEXT: daddu $1, $1, $25
20432054
; N64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(insert_v2i64_vidx)))
20442055
; N64-NEXT: ld $2, %got_disp(i32)($1)
2045-
; N64-NEXT: lwu $2, 0($2)
2056+
; N64-NEXT: lw $2, 0($2)
2057+
; N64-NEXT: andi $2, $2, 1
20462058
; N64-NEXT: ld $1, %got_disp(v2i64)($1)
20472059
; N64-NEXT: dlsa $1, $2, $1, 3
20482060
; N64-NEXT: jr $ra

llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -319,20 +319,13 @@ define <32 x i16> @insertelt_v32i16(<32 x i16> %a, i16 %y, i32 %idx) {
319319
}
320320

321321
define void @insertelt_v32i16_store(ptr %x, i16 %y, i32 %idx) {
322-
; RV32-LABEL: insertelt_v32i16_store:
323-
; RV32: # %bb.0:
324-
; RV32-NEXT: slli a2, a2, 1
325-
; RV32-NEXT: add a0, a0, a2
326-
; RV32-NEXT: sh a1, 0(a0)
327-
; RV32-NEXT: ret
328-
;
329-
; RV64-LABEL: insertelt_v32i16_store:
330-
; RV64: # %bb.0:
331-
; RV64-NEXT: slli a2, a2, 32
332-
; RV64-NEXT: srli a2, a2, 31
333-
; RV64-NEXT: add a0, a0, a2
334-
; RV64-NEXT: sh a1, 0(a0)
335-
; RV64-NEXT: ret
322+
; CHECK-LABEL: insertelt_v32i16_store:
323+
; CHECK: # %bb.0:
324+
; CHECK-NEXT: andi a2, a2, 31
325+
; CHECK-NEXT: slli a2, a2, 1
326+
; CHECK-NEXT: add a0, a0, a2
327+
; CHECK-NEXT: sh a1, 0(a0)
328+
; CHECK-NEXT: ret
336329
%a = load <32 x i16>, ptr %x
337330
%b = insertelement <32 x i16> %a, i16 %y, i32 %idx
338331
store <32 x i16> %b, ptr %x
@@ -364,20 +357,13 @@ define <8 x float> @insertelt_v8f32(<8 x float> %a, float %y, i32 %idx) {
364357
}
365358

366359
define void @insertelt_v8f32_store(ptr %x, float %y, i32 %idx) {
367-
; RV32-LABEL: insertelt_v8f32_store:
368-
; RV32: # %bb.0:
369-
; RV32-NEXT: slli a1, a1, 2
370-
; RV32-NEXT: add a0, a0, a1
371-
; RV32-NEXT: fsw fa0, 0(a0)
372-
; RV32-NEXT: ret
373-
;
374-
; RV64-LABEL: insertelt_v8f32_store:
375-
; RV64: # %bb.0:
376-
; RV64-NEXT: slli a1, a1, 32
377-
; RV64-NEXT: srli a1, a1, 30
378-
; RV64-NEXT: add a0, a0, a1
379-
; RV64-NEXT: fsw fa0, 0(a0)
380-
; RV64-NEXT: ret
360+
; CHECK-LABEL: insertelt_v8f32_store:
361+
; CHECK: # %bb.0:
362+
; CHECK-NEXT: andi a1, a1, 7
363+
; CHECK-NEXT: slli a1, a1, 2
364+
; CHECK-NEXT: add a0, a0, a1
365+
; CHECK-NEXT: fsw fa0, 0(a0)
366+
; CHECK-NEXT: ret
381367
%a = load <8 x float>, ptr %x
382368
%b = insertelement <8 x float> %a, float %y, i32 %idx
383369
store <8 x float> %b, ptr %x
@@ -441,6 +427,7 @@ define <8 x i64> @insertelt_v8i64(<8 x i64> %a, i32 %idx) {
441427
define void @insertelt_v8i64_store(ptr %x, i32 %idx) {
442428
; RV32-LABEL: insertelt_v8i64_store:
443429
; RV32: # %bb.0:
430+
; RV32-NEXT: andi a1, a1, 7
444431
; RV32-NEXT: slli a1, a1, 3
445432
; RV32-NEXT: add a0, a0, a1
446433
; RV32-NEXT: li a1, -1
@@ -450,8 +437,8 @@ define void @insertelt_v8i64_store(ptr %x, i32 %idx) {
450437
;
451438
; RV64-LABEL: insertelt_v8i64_store:
452439
; RV64: # %bb.0:
453-
; RV64-NEXT: slli a1, a1, 32
454-
; RV64-NEXT: srli a1, a1, 29
440+
; RV64-NEXT: andi a1, a1, 7
441+
; RV64-NEXT: slli a1, a1, 3
455442
; RV64-NEXT: add a0, a0, a1
456443
; RV64-NEXT: li a1, -1
457444
; RV64-NEXT: sd a1, 0(a0)
@@ -519,6 +506,7 @@ define <8 x i64> @insertelt_c6_v8i64(<8 x i64> %a, i32 %idx) {
519506
define void @insertelt_c6_v8i64_store(ptr %x, i32 %idx) {
520507
; RV32-LABEL: insertelt_c6_v8i64_store:
521508
; RV32: # %bb.0:
509+
; RV32-NEXT: andi a1, a1, 7
522510
; RV32-NEXT: slli a1, a1, 3
523511
; RV32-NEXT: add a0, a0, a1
524512
; RV32-NEXT: sw zero, 4(a0)
@@ -528,8 +516,8 @@ define void @insertelt_c6_v8i64_store(ptr %x, i32 %idx) {
528516
;
529517
; RV64-LABEL: insertelt_c6_v8i64_store:
530518
; RV64: # %bb.0:
531-
; RV64-NEXT: slli a1, a1, 32
532-
; RV64-NEXT: srli a1, a1, 29
519+
; RV64-NEXT: andi a1, a1, 7
520+
; RV64-NEXT: slli a1, a1, 3
533521
; RV64-NEXT: add a0, a0, a1
534522
; RV64-NEXT: li a1, 6
535523
; RV64-NEXT: sd a1, 0(a0)

llvm/test/CodeGen/X86/pr59980.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ define void @foo(ptr %0, ptr %1, ptr %2) #0 {
99
; CHECK: ## %bb.0:
1010
; CHECK-NEXT: movl (%rdx), %eax
1111
; CHECK-NEXT: vpinsrw $0, (%rdi), %xmm0, %xmm0
12+
; CHECK-NEXT: andl $15, %eax
1213
; CHECK-NEXT: vpextrw $0, %xmm0, (%rsi,%rax,2)
1314
; CHECK-NEXT: retq
1415
%4 = bitcast ptr %2 to ptr

0 commit comments

Comments
 (0)