forked from OSchip/llvm-project
[PowerPC] Correctly compute 64-bit offsets in fast isel
PPCSimplifyAddress contains this code: IntegerType *OffsetTy = ((VT == MVT::i32) ? Type::getInt32Ty(*Context) : Type::getInt64Ty(*Context)); to determine the type to be used for an index register, if one needs to be created. However, the "VT" here is the type of the data being loaded or stored, *not* the type of an address. This means that if a data element of type i32 is accessed using an index that does not not fit into 32 bits, a wrong address is computed here. Note that PPCFastISel is only ever used on 64-bit currently, so the type of an address is actually *always* MVT::i64. Other parts of the code, even in this same PPCSimplifyAddress routine, already rely on that fact. Thus, this patch changes the code to simply unconditionally use Type::getInt64Ty(*Context) as OffsetTy. llvm-svn: 265023
This commit is contained in:
parent
a621a7f9c3
commit
3707ba8030
|
@ -158,7 +158,7 @@ class PPCFastISel final : public FastISel {
|
|||
unsigned FP64LoadOpc = PPC::LFD);
|
||||
bool PPCEmitStore(MVT VT, unsigned SrcReg, Address &Addr);
|
||||
bool PPCComputeAddress(const Value *Obj, Address &Addr);
|
||||
void PPCSimplifyAddress(Address &Addr, MVT VT, bool &UseOffset,
|
||||
void PPCSimplifyAddress(Address &Addr, bool &UseOffset,
|
||||
unsigned &IndexReg);
|
||||
bool PPCEmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
|
||||
unsigned DestReg, bool IsZExt);
|
||||
|
@ -428,7 +428,7 @@ bool PPCFastISel::PPCComputeAddress(const Value *Obj, Address &Addr) {
|
|||
// Fix up some addresses that can't be used directly. For example, if
|
||||
// an offset won't fit in an instruction field, we may need to move it
|
||||
// into an index register.
|
||||
void PPCFastISel::PPCSimplifyAddress(Address &Addr, MVT VT, bool &UseOffset,
|
||||
void PPCFastISel::PPCSimplifyAddress(Address &Addr, bool &UseOffset,
|
||||
unsigned &IndexReg) {
|
||||
|
||||
// Check whether the offset fits in the instruction field.
|
||||
|
@ -447,8 +447,7 @@ void PPCFastISel::PPCSimplifyAddress(Address &Addr, MVT VT, bool &UseOffset,
|
|||
}
|
||||
|
||||
if (!UseOffset) {
|
||||
IntegerType *OffsetTy = ((VT == MVT::i32) ? Type::getInt32Ty(*Context)
|
||||
: Type::getInt64Ty(*Context));
|
||||
IntegerType *OffsetTy = Type::getInt64Ty(*Context);
|
||||
const ConstantInt *Offset =
|
||||
ConstantInt::getSigned(OffsetTy, (int64_t)(Addr.Offset));
|
||||
IndexReg = PPCMaterializeInt(Offset, MVT::i64);
|
||||
|
@ -517,7 +516,7 @@ bool PPCFastISel::PPCEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
|
|||
// If necessary, materialize the offset into a register and use
|
||||
// the indexed form. Also handle stack pointers with special needs.
|
||||
unsigned IndexReg = 0;
|
||||
PPCSimplifyAddress(Addr, VT, UseOffset, IndexReg);
|
||||
PPCSimplifyAddress(Addr, UseOffset, IndexReg);
|
||||
|
||||
// If this is a potential VSX load with an offset of 0, a VSX indexed load can
|
||||
// be used.
|
||||
|
@ -653,7 +652,7 @@ bool PPCFastISel::PPCEmitStore(MVT VT, unsigned SrcReg, Address &Addr) {
|
|||
// If necessary, materialize the offset into a register and use
|
||||
// the indexed form. Also handle stack pointers with special needs.
|
||||
unsigned IndexReg = 0;
|
||||
PPCSimplifyAddress(Addr, VT, UseOffset, IndexReg);
|
||||
PPCSimplifyAddress(Addr, UseOffset, IndexReg);
|
||||
|
||||
// If this is a potential VSX store with an offset of 0, a VSX indexed store
|
||||
// can be used.
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
; RUN: llc -mtriple powerpc64-unknown-linux-gnu -fast-isel -O0 < %s | FileCheck %s
|
||||
|
||||
; Verify that pointer offsets larger than 32 bits work correctly.
|
||||
|
||||
define void @test(i32* %array) {
|
||||
; CHECK-LABEL: test:
|
||||
; CHECK: lis [[REG:[0-9]+]], 16383
|
||||
; CHECK: ori [[REG]], [[REG]], 65535
|
||||
; CHECK: sldi [[REG]], [[REG]], 3
|
||||
; CHECK: stwx {{[0-9]+}}, 3, [[REG]]
|
||||
%element = getelementptr i32, i32* %array, i64 2147483646
|
||||
store i32 1234, i32* %element
|
||||
ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue