Skip to content

Commit

Permalink
[SelectionDAG] Use unaligned store to move AVX registers onto stack f…
Browse files Browse the repository at this point in the history
…or `extractelement` (#78422)

Prior to this patch, SelectionDAG generated aligned move onto stacks for
AVX registers when the function was marked as a no-realign-stack
function. This lead to misalignment between the stack and the
instruction generated. This patch fixes the issue.

Fixes #77730
  • Loading branch information
Nirhar authored Feb 2, 2024
1 parent b78b264 commit a768bc6
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
21 changes: 19 additions & 2 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineMemOperand.h"
Expand Down Expand Up @@ -1377,6 +1378,21 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
}
}

// Helper function that generates an MMO that considers the alignment of the
// stack, and the size of the stack object
static MachineMemOperand *getStackAlignedMMO(SDValue StackPtr,
MachineFunction &MF,
bool isObjectScalable) {
auto &MFI = MF.getFrameInfo();
int FI = cast<FrameIndexSDNode>(StackPtr)->getIndex();
MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FI);
uint64_t ObjectSize = isObjectScalable ? ~UINT64_C(0) : MFI.getObjectSize(FI);
MachineMemOperand *MMO = MF.getMachineMemOperand(
PtrInfo, MachineMemOperand::MOStore, ObjectSize, MFI.getObjectAlign(FI));

return MMO;
}

SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) {
SDValue Vec = Op.getOperand(0);
SDValue Idx = Op.getOperand(1);
Expand Down Expand Up @@ -1426,8 +1442,9 @@ SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) {
if (!Ch.getNode()) {
// Store the value to a temporary stack slot, then LOAD the returned part.
StackPtr = DAG.CreateStackTemporary(VecVT);
Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr,
MachinePointerInfo());
MachineMemOperand *StoreMMO = getStackAlignedMMO(
StackPtr, DAG.getMachineFunction(), VecVT.isScalableVector());
Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, StoreMMO);
}

SDValue NewLoad;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s

define i32 @foo(i32 %arg1) #0 {
; CHECK-LABEL: foo:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
; CHECK-NEXT: vxorps %xmm0, %xmm0, %xmm0
; CHECK-NEXT: vmovups %ymm0, -{{[0-9]+}}(%rsp)
; CHECK-NEXT: andl $31, %edi
; CHECK-NEXT: movzbl -40(%rsp,%rdi), %eax
; CHECK-NEXT: vzeroupper
; CHECK-NEXT: retq
entry:
%a = extractelement <32 x i8> zeroinitializer, i32 %arg1
%b = zext i8 %a to i32
ret i32 %b
}

attributes #0 = { "no-realign-stack" "target-cpu"="skylake-avx512" }

0 comments on commit a768bc6

Please sign in to comment.