summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2016-03-31 15:37:06 +0000
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2016-03-31 15:37:06 +0000
commit3707ba80302b184c850ccdab2191650b75486742 (patch)
tree311ca1ffe77dff4042cc8c41977a3067459ff22c
parenta621a7f9c30b86f7c38487ab2c24dea4b14043b3 (diff)
downloadbcm5719-llvm-3707ba80302b184c850ccdab2191650b75486742.tar.gz
bcm5719-llvm-3707ba80302b184c850ccdab2191650b75486742.zip
[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
-rw-r--r--llvm/lib/Target/PowerPC/PPCFastISel.cpp11
-rw-r--r--llvm/test/CodeGen/PowerPC/fast-isel-i64offset.ll15
2 files changed, 20 insertions, 6 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/llvm/lib/Target/PowerPC/PPCFastISel.cpp
index 901a7502cb2..0f4dee3ded4 100644
--- a/llvm/lib/Target/PowerPC/PPCFastISel.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFastISel.cpp
@@ -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.
diff --git a/llvm/test/CodeGen/PowerPC/fast-isel-i64offset.ll b/llvm/test/CodeGen/PowerPC/fast-isel-i64offset.ll
new file mode 100644
index 00000000000..e184ce4c3b3
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/fast-isel-i64offset.ll
@@ -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
+}
+
OpenPOWER on IntegriCloud