mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-02 22:23:10 +00:00
[FastISel][AArch64] Fix load/store with frame indices.
At higher optimization levels the LLVM IR may contain more complex patterns for loads/stores from/to frame indices. The 'computeAddress' function wasn't able to handle this and triggered an assertion. This fix extends the possible addressing modes for frame indices. This fixes rdar://problem/18783298. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220700 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -78,11 +78,9 @@ class AArch64FastISel final : public FastISel {
|
|||||||
return Base.Reg;
|
return Base.Reg;
|
||||||
}
|
}
|
||||||
void setOffsetReg(unsigned Reg) {
|
void setOffsetReg(unsigned Reg) {
|
||||||
assert(isRegBase() && "Invalid offset register access!");
|
|
||||||
OffsetReg = Reg;
|
OffsetReg = Reg;
|
||||||
}
|
}
|
||||||
unsigned getOffsetReg() const {
|
unsigned getOffsetReg() const {
|
||||||
assert(isRegBase() && "Invalid offset register access!");
|
|
||||||
return OffsetReg;
|
return OffsetReg;
|
||||||
}
|
}
|
||||||
void setFI(unsigned FI) {
|
void setFI(unsigned FI) {
|
||||||
@@ -810,22 +808,23 @@ bool AArch64FastISel::computeAddress(const Value *Obj, Address &Addr, Type *Ty)
|
|||||||
}
|
}
|
||||||
} // end switch
|
} // end switch
|
||||||
|
|
||||||
if (Addr.getReg()) {
|
if (Addr.isRegBase() && !Addr.getReg()) {
|
||||||
if (!Addr.getOffsetReg()) {
|
unsigned Reg = getRegForValue(Obj);
|
||||||
unsigned Reg = getRegForValue(Obj);
|
if (!Reg)
|
||||||
if (!Reg)
|
return false;
|
||||||
return false;
|
Addr.setReg(Reg);
|
||||||
Addr.setOffsetReg(Reg);
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Reg = getRegForValue(Obj);
|
if (!Addr.getOffsetReg()) {
|
||||||
if (!Reg)
|
unsigned Reg = getRegForValue(Obj);
|
||||||
return false;
|
if (!Reg)
|
||||||
Addr.setReg(Reg);
|
return false;
|
||||||
return true;
|
Addr.setOffsetReg(Reg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AArch64FastISel::computeCallAddress(const Value *V, Address &Addr) {
|
bool AArch64FastISel::computeCallAddress(const Value *V, Address &Addr) {
|
||||||
@@ -942,8 +941,7 @@ bool AArch64FastISel::simplifyAddress(Address &Addr, MVT VT) {
|
|||||||
// Cannot encode an offset register and an immediate offset in the same
|
// Cannot encode an offset register and an immediate offset in the same
|
||||||
// instruction. Fold the immediate offset into the load/store instruction and
|
// instruction. Fold the immediate offset into the load/store instruction and
|
||||||
// emit an additonal add to take care of the offset register.
|
// emit an additonal add to take care of the offset register.
|
||||||
if (!ImmediateOffsetNeedsLowering && Addr.getOffset() && Addr.isRegBase() &&
|
if (!ImmediateOffsetNeedsLowering && Addr.getOffset() && Addr.getOffsetReg())
|
||||||
Addr.getOffsetReg())
|
|
||||||
RegisterOffsetNeedsLowering = true;
|
RegisterOffsetNeedsLowering = true;
|
||||||
|
|
||||||
// Cannot encode zero register as base.
|
// Cannot encode zero register as base.
|
||||||
@@ -953,7 +951,8 @@ bool AArch64FastISel::simplifyAddress(Address &Addr, MVT VT) {
|
|||||||
// If this is a stack pointer and the offset needs to be simplified then put
|
// If this is a stack pointer and the offset needs to be simplified then put
|
||||||
// the alloca address into a register, set the base type back to register and
|
// the alloca address into a register, set the base type back to register and
|
||||||
// continue. This should almost never happen.
|
// continue. This should almost never happen.
|
||||||
if (ImmediateOffsetNeedsLowering && Addr.isFIBase()) {
|
if ((ImmediateOffsetNeedsLowering || Addr.getOffsetReg()) && Addr.isFIBase())
|
||||||
|
{
|
||||||
unsigned ResultReg = createResultReg(&AArch64::GPR64spRegClass);
|
unsigned ResultReg = createResultReg(&AArch64::GPR64spRegClass);
|
||||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADDXri),
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADDXri),
|
||||||
ResultReg)
|
ResultReg)
|
||||||
@@ -1050,10 +1049,8 @@ void AArch64FastISel::addLoadStoreOperands(Address &Addr,
|
|||||||
MIB.addReg(Addr.getOffsetReg());
|
MIB.addReg(Addr.getOffsetReg());
|
||||||
MIB.addImm(IsSigned);
|
MIB.addImm(IsSigned);
|
||||||
MIB.addImm(Addr.getShift() != 0);
|
MIB.addImm(Addr.getShift() != 0);
|
||||||
} else {
|
} else
|
||||||
MIB.addReg(Addr.getReg());
|
MIB.addReg(Addr.getReg()).addImm(Offset);
|
||||||
MIB.addImm(Offset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MMO)
|
if (MMO)
|
||||||
|
|||||||
@@ -599,3 +599,29 @@ define i64 @kill_reg(i64 %a) {
|
|||||||
ret i64 %5
|
ret i64 %5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define void @store_fi(i64 %i) {
|
||||||
|
; CHECK-LABEL: store_fi
|
||||||
|
; CHECK: mov [[REG:x[0-9]+]], sp
|
||||||
|
; CHECK: str {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
|
||||||
|
%1 = alloca [8 x i32]
|
||||||
|
%2 = ptrtoint [8 x i32]* %1 to i64
|
||||||
|
%3 = mul i64 %i, 4
|
||||||
|
%4 = add i64 %2, %3
|
||||||
|
%5 = inttoptr i64 %4 to i32*
|
||||||
|
store i32 47, i32* %5, align 4
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @load_fi(i64 %i) {
|
||||||
|
; CHECK-LABEL: load_fi
|
||||||
|
; CHECK: mov [[REG:x[0-9]+]], sp
|
||||||
|
; CHECK: ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
|
||||||
|
%1 = alloca [8 x i32]
|
||||||
|
%2 = ptrtoint [8 x i32]* %1 to i64
|
||||||
|
%3 = mul i64 %i, 4
|
||||||
|
%4 = add i64 %2, %3
|
||||||
|
%5 = inttoptr i64 %4 to i32*
|
||||||
|
%6 = load i32* %5, align 4
|
||||||
|
ret i32 %6
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user