Skip to content

[SelectionDAG] Use getVectorElementPointer in DAGCombiner::replaceStoreOfInsertLoad. #74249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21006,20 +21006,18 @@ SDValue DAGCombiner::replaceStoreOfInsertLoad(StoreSDNode *ST) {
&IsFast) ||
!IsFast)
return SDValue();
EVT PtrVT = Ptr.getValueType();

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

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

return DAG.getStore(Chain, DL, Elt, NewPtr, PointerInfo, ST->getAlign(),
Expand Down
20 changes: 16 additions & 4 deletions llvm/test/CodeGen/Mips/msa/basic_operations.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1879,6 +1879,7 @@ define void @insert_v16i8_vidx(i32 signext %a) nounwind {
; O32-NEXT: addu $1, $2, $25
; O32-NEXT: lw $2, %got(i32)($1)
; O32-NEXT: lw $2, 0($2)
; O32-NEXT: andi $2, $2, 15
; O32-NEXT: lw $1, %got(v16i8)($1)
; O32-NEXT: addu $1, $1, $2
; O32-NEXT: jr $ra
Expand All @@ -1891,6 +1892,7 @@ define void @insert_v16i8_vidx(i32 signext %a) nounwind {
; N32-NEXT: addiu $1, $1, %lo(%neg(%gp_rel(insert_v16i8_vidx)))
; N32-NEXT: lw $2, %got_disp(i32)($1)
; N32-NEXT: lw $2, 0($2)
; N32-NEXT: andi $2, $2, 15
; N32-NEXT: lw $1, %got_disp(v16i8)($1)
; N32-NEXT: addu $1, $1, $2
; N32-NEXT: jr $ra
Expand All @@ -1902,7 +1904,8 @@ define void @insert_v16i8_vidx(i32 signext %a) nounwind {
; N64-NEXT: daddu $1, $1, $25
; N64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(insert_v16i8_vidx)))
; N64-NEXT: ld $2, %got_disp(i32)($1)
; N64-NEXT: lwu $2, 0($2)
; N64-NEXT: lw $2, 0($2)
; N64-NEXT: andi $2, $2, 15
; N64-NEXT: ld $1, %got_disp(v16i8)($1)
; N64-NEXT: daddu $1, $1, $2
; N64-NEXT: jr $ra
Expand All @@ -1925,6 +1928,7 @@ define void @insert_v8i16_vidx(i32 signext %a) nounwind {
; O32-NEXT: addu $1, $2, $25
; O32-NEXT: lw $2, %got(i32)($1)
; O32-NEXT: lw $2, 0($2)
; O32-NEXT: andi $2, $2, 7
; O32-NEXT: lw $1, %got(v8i16)($1)
; O32-NEXT: lsa $1, $2, $1, 1
; O32-NEXT: jr $ra
Expand All @@ -1937,6 +1941,7 @@ define void @insert_v8i16_vidx(i32 signext %a) nounwind {
; N32-NEXT: addiu $1, $1, %lo(%neg(%gp_rel(insert_v8i16_vidx)))
; N32-NEXT: lw $2, %got_disp(i32)($1)
; N32-NEXT: lw $2, 0($2)
; N32-NEXT: andi $2, $2, 7
; N32-NEXT: lw $1, %got_disp(v8i16)($1)
; N32-NEXT: lsa $1, $2, $1, 1
; N32-NEXT: jr $ra
Expand All @@ -1948,7 +1953,8 @@ define void @insert_v8i16_vidx(i32 signext %a) nounwind {
; N64-NEXT: daddu $1, $1, $25
; N64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(insert_v8i16_vidx)))
; N64-NEXT: ld $2, %got_disp(i32)($1)
; N64-NEXT: lwu $2, 0($2)
; N64-NEXT: lw $2, 0($2)
; N64-NEXT: andi $2, $2, 7
; N64-NEXT: ld $1, %got_disp(v8i16)($1)
; N64-NEXT: dlsa $1, $2, $1, 1
; N64-NEXT: jr $ra
Expand All @@ -1971,6 +1977,7 @@ define void @insert_v4i32_vidx(i32 signext %a) nounwind {
; O32-NEXT: addu $1, $2, $25
; O32-NEXT: lw $2, %got(i32)($1)
; O32-NEXT: lw $2, 0($2)
; O32-NEXT: andi $2, $2, 3
; O32-NEXT: lw $1, %got(v4i32)($1)
; O32-NEXT: lsa $1, $2, $1, 2
; O32-NEXT: jr $ra
Expand All @@ -1983,6 +1990,7 @@ define void @insert_v4i32_vidx(i32 signext %a) nounwind {
; N32-NEXT: addiu $1, $1, %lo(%neg(%gp_rel(insert_v4i32_vidx)))
; N32-NEXT: lw $2, %got_disp(i32)($1)
; N32-NEXT: lw $2, 0($2)
; N32-NEXT: andi $2, $2, 3
; N32-NEXT: lw $1, %got_disp(v4i32)($1)
; N32-NEXT: lsa $1, $2, $1, 2
; N32-NEXT: jr $ra
Expand All @@ -1994,7 +2002,8 @@ define void @insert_v4i32_vidx(i32 signext %a) nounwind {
; N64-NEXT: daddu $1, $1, $25
; N64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(insert_v4i32_vidx)))
; N64-NEXT: ld $2, %got_disp(i32)($1)
; N64-NEXT: lwu $2, 0($2)
; N64-NEXT: lw $2, 0($2)
; N64-NEXT: andi $2, $2, 3
; N64-NEXT: ld $1, %got_disp(v4i32)($1)
; N64-NEXT: dlsa $1, $2, $1, 2
; N64-NEXT: jr $ra
Expand All @@ -2018,6 +2027,7 @@ define void @insert_v2i64_vidx(i64 signext %a) nounwind {
; O32-NEXT: addu $1, $2, $25
; O32-NEXT: lw $2, %got(i32)($1)
; O32-NEXT: lw $2, 0($2)
; O32-NEXT: andi $2, $2, 1
; O32-NEXT: lw $1, %got(v2i64)($1)
; O32-NEXT: lsa $1, $2, $1, 3
; O32-NEXT: sw $5, 4($1)
Expand All @@ -2031,6 +2041,7 @@ define void @insert_v2i64_vidx(i64 signext %a) nounwind {
; N32-NEXT: addiu $1, $1, %lo(%neg(%gp_rel(insert_v2i64_vidx)))
; N32-NEXT: lw $2, %got_disp(i32)($1)
; N32-NEXT: lw $2, 0($2)
; N32-NEXT: andi $2, $2, 1
; N32-NEXT: lw $1, %got_disp(v2i64)($1)
; N32-NEXT: lsa $1, $2, $1, 3
; N32-NEXT: jr $ra
Expand All @@ -2042,7 +2053,8 @@ define void @insert_v2i64_vidx(i64 signext %a) nounwind {
; N64-NEXT: daddu $1, $1, $25
; N64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(insert_v2i64_vidx)))
; N64-NEXT: ld $2, %got_disp(i32)($1)
; N64-NEXT: lwu $2, 0($2)
; N64-NEXT: lw $2, 0($2)
; N64-NEXT: andi $2, $2, 1
; N64-NEXT: ld $1, %got_disp(v2i64)($1)
; N64-NEXT: dlsa $1, $2, $1, 3
; N64-NEXT: jr $ra
Expand Down
52 changes: 20 additions & 32 deletions llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll
Original file line number Diff line number Diff line change
Expand Up @@ -321,20 +321,13 @@ define <32 x i16> @insertelt_v32i16(<32 x i16> %a, i16 %y, i32 %idx) {
}

define void @insertelt_v32i16_store(ptr %x, i16 %y, i32 %idx) {
; RV32-LABEL: insertelt_v32i16_store:
; RV32: # %bb.0:
; RV32-NEXT: slli a2, a2, 1
; RV32-NEXT: add a0, a0, a2
; RV32-NEXT: sh a1, 0(a0)
; RV32-NEXT: ret
;
; RV64-LABEL: insertelt_v32i16_store:
; RV64: # %bb.0:
; RV64-NEXT: slli a2, a2, 32
; RV64-NEXT: srli a2, a2, 31
; RV64-NEXT: add a0, a0, a2
; RV64-NEXT: sh a1, 0(a0)
; RV64-NEXT: ret
; CHECK-LABEL: insertelt_v32i16_store:
; CHECK: # %bb.0:
; CHECK-NEXT: andi a2, a2, 31
; CHECK-NEXT: slli a2, a2, 1
; CHECK-NEXT: add a0, a0, a2
; CHECK-NEXT: sh a1, 0(a0)
; CHECK-NEXT: ret
%a = load <32 x i16>, ptr %x
%b = insertelement <32 x i16> %a, i16 %y, i32 %idx
store <32 x i16> %b, ptr %x
Expand Down Expand Up @@ -366,20 +359,13 @@ define <8 x float> @insertelt_v8f32(<8 x float> %a, float %y, i32 %idx) {
}

define void @insertelt_v8f32_store(ptr %x, float %y, i32 %idx) {
; RV32-LABEL: insertelt_v8f32_store:
; RV32: # %bb.0:
; RV32-NEXT: slli a1, a1, 2
; RV32-NEXT: add a0, a0, a1
; RV32-NEXT: fsw fa0, 0(a0)
; RV32-NEXT: ret
;
; RV64-LABEL: insertelt_v8f32_store:
; RV64: # %bb.0:
; RV64-NEXT: slli a1, a1, 32
; RV64-NEXT: srli a1, a1, 30
; RV64-NEXT: add a0, a0, a1
; RV64-NEXT: fsw fa0, 0(a0)
; RV64-NEXT: ret
; CHECK-LABEL: insertelt_v8f32_store:
; CHECK: # %bb.0:
; CHECK-NEXT: andi a1, a1, 7
; CHECK-NEXT: slli a1, a1, 2
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: fsw fa0, 0(a0)
; CHECK-NEXT: ret
%a = load <8 x float>, ptr %x
%b = insertelement <8 x float> %a, float %y, i32 %idx
store <8 x float> %b, ptr %x
Expand Down Expand Up @@ -443,6 +429,7 @@ define <8 x i64> @insertelt_v8i64(<8 x i64> %a, i32 %idx) {
define void @insertelt_v8i64_store(ptr %x, i32 %idx) {
; RV32-LABEL: insertelt_v8i64_store:
; RV32: # %bb.0:
; RV32-NEXT: andi a1, a1, 7
; RV32-NEXT: slli a1, a1, 3
; RV32-NEXT: add a0, a0, a1
; RV32-NEXT: li a1, -1
Expand All @@ -452,8 +439,8 @@ define void @insertelt_v8i64_store(ptr %x, i32 %idx) {
;
; RV64-LABEL: insertelt_v8i64_store:
; RV64: # %bb.0:
; RV64-NEXT: slli a1, a1, 32
; RV64-NEXT: srli a1, a1, 29
; RV64-NEXT: andi a1, a1, 7
; RV64-NEXT: slli a1, a1, 3
; RV64-NEXT: add a0, a0, a1
; RV64-NEXT: li a1, -1
; RV64-NEXT: sd a1, 0(a0)
Expand Down Expand Up @@ -521,6 +508,7 @@ define <8 x i64> @insertelt_c6_v8i64(<8 x i64> %a, i32 %idx) {
define void @insertelt_c6_v8i64_store(ptr %x, i32 %idx) {
; RV32-LABEL: insertelt_c6_v8i64_store:
; RV32: # %bb.0:
; RV32-NEXT: andi a1, a1, 7
; RV32-NEXT: slli a1, a1, 3
; RV32-NEXT: add a0, a0, a1
; RV32-NEXT: sw zero, 4(a0)
Expand All @@ -530,8 +518,8 @@ define void @insertelt_c6_v8i64_store(ptr %x, i32 %idx) {
;
; RV64-LABEL: insertelt_c6_v8i64_store:
; RV64: # %bb.0:
; RV64-NEXT: slli a1, a1, 32
; RV64-NEXT: srli a1, a1, 29
; RV64-NEXT: andi a1, a1, 7
; RV64-NEXT: slli a1, a1, 3
; RV64-NEXT: add a0, a0, a1
; RV64-NEXT: li a1, 6
; RV64-NEXT: sd a1, 0(a0)
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/X86/pr59980.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ define void @foo(ptr %0, ptr %1, ptr %2) #0 {
; CHECK: ## %bb.0:
; CHECK-NEXT: movl (%rdx), %eax
; CHECK-NEXT: vpinsrw $0, (%rdi), %xmm0, %xmm0
; CHECK-NEXT: andl $15, %eax
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do we need to limit the range? The LangRef says "If idx exceeds the length of val for a fixed-length vector, the result is a poison value."

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do we need to limit the range? The LangRef says "If idx exceeds the length of val for a fixed-length vector, the result is a poison value."

Since we convert the index to be part of the address we can store outside the bounds of the original store. When it was a vector store only the vector starting at the base address was poisoned.

Copy link
Contributor

@phoebewang phoebewang Dec 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the problem, thanks! It looks like a serious security issue.

; CHECK-NEXT: vpextrw $0, %xmm0, (%rsi,%rax,2)
; CHECK-NEXT: retq
%4 = bitcast ptr %2 to ptr
Expand Down