Skip to content

Commit 18b8266

Browse files
sstefan1gerekon
authored andcommitted
[Xtensa] Alignment fix
1 parent 2662180 commit 18b8266

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
/*/build-*
3232
/_build
3333
/_dist
34+
/dbg
3435

3536
#==============================================================================#
3637
# Explicit files to ignore (only matches one).

llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
6262

6363
if (STI.isWinABI()) {
6464
StackSize += 32;
65+
uint64_t MaxAlignment = MFI.getMaxAlign().value();
66+
if(MaxAlignment > 32)
67+
StackSize += MaxAlignment;
6568

6669
if (StackSize <= 32760) {
6770
BuildMI(MBB, MBBI, DL, TII.get(Xtensa::ENTRY))
@@ -83,6 +86,28 @@ void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
8386
BuildMI(MBB, MBBI, DL, TII.get(Xtensa::MOVSP), SP).addReg(TmpReg);
8487
}
8588

89+
// Calculate how much is needed to have the correct alignment.
90+
// Change offset to: alignment + difference.
91+
// For example, in case of alignment of 128:
92+
// diff_to_128_aligned_address = (128 - (SP & 127))
93+
// new_offset = 128 + diff_to_128_aligned_address
94+
// This is safe to do because we increased the stack size by MaxAlignment.
95+
unsigned Reg, RegMisAlign;
96+
if (MaxAlignment > 32){
97+
TII.loadImmediate(MBB, MBBI, &RegMisAlign, MaxAlignment - 1);
98+
TII.loadImmediate(MBB, MBBI, &Reg, MaxAlignment);
99+
BuildMI(MBB, MBBI, DL, TII.get(Xtensa::AND))
100+
.addReg(RegMisAlign, RegState::Define)
101+
.addReg(FP)
102+
.addReg(RegMisAlign);
103+
BuildMI(MBB, MBBI, DL, TII.get(Xtensa::SUB), RegMisAlign)
104+
.addReg(Reg)
105+
.addReg(RegMisAlign);
106+
BuildMI(MBB, MBBI, DL, TII.get(Xtensa::ADD), SP)
107+
.addReg(SP)
108+
.addReg(RegMisAlign, RegState::Kill);
109+
}
110+
86111
// Store FP register in A8, because FP may be used to pass function
87112
// arguments
88113
if (XtensaFI->isSaveFrameRegister()) {

llvm/lib/Target/Xtensa/XtensaRegisterInfo.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,20 +119,21 @@ bool XtensaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
119119
int64_t Offset =
120120
SPOffset + (int64_t)StackSize + MI.getOperand(FIOperandNum + 1).getImm();
121121

122+
uint64_t Alignment = MF.getFrameInfo().getObjectAlign(FrameIndex).value();
122123
bool Valid = isValidAddrOffset(MI, Offset);
123124

124125
// If MI is not a debug value, make sure Offset fits in the 16-bit immediate
125126
// field.
126127
if (!MI.isDebugValue() && !Valid) {
127128
MachineBasicBlock &MBB = *MI.getParent();
128129
DebugLoc DL = II->getDebugLoc();
129-
unsigned ADD = Xtensa::ADD;
130130
unsigned Reg;
131131
const XtensaInstrInfo &TII = *static_cast<const XtensaInstrInfo *>(
132132
MBB.getParent()->getSubtarget().getInstrInfo());
133133

134134
TII.loadImmediate(MBB, II, &Reg, Offset);
135-
BuildMI(MBB, II, DL, TII.get(ADD), Reg)
135+
136+
BuildMI(MBB, II, DL, TII.get(Xtensa::ADD), Reg)
136137
.addReg(FrameReg)
137138
.addReg(Reg, RegState::Kill);
138139

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=xtensa -O0 -verify-machineinstrs < %s \
3+
; RUN: | FileCheck %s -check-prefix=XTENSA
4+
5+
define i8 @loadi8_128(i8 %a) {
6+
; XTENSA-LABEL: loadi8_128:
7+
; XTENSA: entry a1, 416
8+
; XTENSA-NEXT: movi a8, 127
9+
; XTENSA-NEXT: movi a9, 128
10+
; XTENSA-NEXT: and a8, a1, a8
11+
; XTENSA-NEXT: sub a8, a9, a8
12+
; XTENSA-NEXT: add.n a1, a1, a8
13+
; XTENSA-NEXT: movi a8, 128
14+
; XTENSA-NEXT: add.n a8, a1, a8
15+
; XTENSA-NEXT: addi a10, a8, 0
16+
; XTENSA-NEXT: movi.n a11, 0
17+
; XTENSA-NEXT: movi.n a12, 64
18+
; XTENSA-NEXT: l32r a8, .LCPI0_0
19+
; XTENSA-NEXT: callx8 a8
20+
; XTENSA-NEXT: l8ui a2, a1, 128
21+
; XTENSA-NEXT: retw.n
22+
%aligned = alloca i8, align 128
23+
call void @llvm.memset.p0.i64(ptr noundef nonnull align 64 dereferenceable(64) %aligned, i8 0, i64 64, i1 false)
24+
%1 = load i8, ptr %aligned, align 128
25+
ret i8 %1
26+
}
27+
28+
; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
29+
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)

0 commit comments

Comments
 (0)