[llvm] r265023 - [PowerPC] Correctly compute 64-bit offsets in fast isel

Ulrich Weigand via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 31 08:37:07 PDT 2016


Author: uweigand
Date: Thu Mar 31 10:37:06 2016
New Revision: 265023

URL: http://llvm.org/viewvc/llvm-project?rev=265023&view=rev
Log:
[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.


Added:
    llvm/trunk/test/CodeGen/PowerPC/fast-isel-i64offset.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp

Modified: llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp?rev=265023&r1=265022&r2=265023&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp Thu Mar 31 10:37:06 2016
@@ -158,7 +158,7 @@ class PPCFastISel final : public FastISe
                      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(cons
 // 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(Add
   }
 
   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, un
   // 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, u
   // 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.

Added: llvm/trunk/test/CodeGen/PowerPC/fast-isel-i64offset.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/fast-isel-i64offset.ll?rev=265023&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/fast-isel-i64offset.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/fast-isel-i64offset.ll Thu Mar 31 10:37:06 2016
@@ -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
+}
+




More information about the llvm-commits mailing list