llvm.org GIT mirror llvm / 9bb23c0
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265023 91177308-0d34-0410-b5e6-96231b3b80d8 Ulrich Weigand 4 years ago
2 changed file(s) with 20 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
157157 unsigned FP64LoadOpc = PPC::LFD);
158158 bool PPCEmitStore(MVT VT, unsigned SrcReg, Address &Addr);
159159 bool PPCComputeAddress(const Value *Obj, Address &Addr);
160 void PPCSimplifyAddress(Address &Addr, MVT VT, bool &UseOffset,
160 void PPCSimplifyAddress(Address &Addr, bool &UseOffset,
161161 unsigned &IndexReg);
162162 bool PPCEmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
163163 unsigned DestReg, bool IsZExt);
427427 // Fix up some addresses that can't be used directly. For example, if
428428 // an offset won't fit in an instruction field, we may need to move it
429429 // into an index register.
430 void PPCFastISel::PPCSimplifyAddress(Address &Addr, MVT VT, bool &UseOffset,
430 void PPCFastISel::PPCSimplifyAddress(Address &Addr, bool &UseOffset,
431431 unsigned &IndexReg) {
432432
433433 // Check whether the offset fits in the instruction field.
446446 }
447447
448448 if (!UseOffset) {
449 IntegerType *OffsetTy = ((VT == MVT::i32) ? Type::getInt32Ty(*Context)
450 : Type::getInt64Ty(*Context));
449 IntegerType *OffsetTy = Type::getInt64Ty(*Context);
451450 const ConstantInt *Offset =
452451 ConstantInt::getSigned(OffsetTy, (int64_t)(Addr.Offset));
453452 IndexReg = PPCMaterializeInt(Offset, MVT::i64);
516515 // If necessary, materialize the offset into a register and use
517516 // the indexed form. Also handle stack pointers with special needs.
518517 unsigned IndexReg = 0;
519 PPCSimplifyAddress(Addr, VT, UseOffset, IndexReg);
518 PPCSimplifyAddress(Addr, UseOffset, IndexReg);
520519
521520 // If this is a potential VSX load with an offset of 0, a VSX indexed load can
522521 // be used.
652651 // If necessary, materialize the offset into a register and use
653652 // the indexed form. Also handle stack pointers with special needs.
654653 unsigned IndexReg = 0;
655 PPCSimplifyAddress(Addr, VT, UseOffset, IndexReg);
654 PPCSimplifyAddress(Addr, UseOffset, IndexReg);
656655
657656 // If this is a potential VSX store with an offset of 0, a VSX indexed store
658657 // can be used.
0 ; RUN: llc -mtriple powerpc64-unknown-linux-gnu -fast-isel -O0 < %s | FileCheck %s
1
2 ; Verify that pointer offsets larger than 32 bits work correctly.
3
4 define void @test(i32* %array) {
5 ; CHECK-LABEL: test:
6 ; CHECK: lis [[REG:[0-9]+]], 16383
7 ; CHECK: ori [[REG]], [[REG]], 65535
8 ; CHECK: sldi [[REG]], [[REG]], 3
9 ; CHECK: stwx {{[0-9]+}}, 3, [[REG]]
10 %element = getelementptr i32, i32* %array, i64 2147483646
11 store i32 1234, i32* %element
12 ret void
13 }
14