@@ -35,7 +35,7 @@ class RISCVMergeBaseOffsetOpt : public MachineFunctionPass {
3535 bool detectFoldable (MachineInstr &Hi, MachineInstr *&Lo);
3636
3737 bool detectAndFoldOffset (MachineInstr &Hi, MachineInstr &Lo);
38- void foldOffset (MachineInstr &Hi, MachineInstr &Lo, MachineInstr &Tail,
38+ bool foldOffset (MachineInstr &Hi, MachineInstr &Lo, MachineInstr &Tail,
3939 int64_t Offset);
4040 bool foldLargeOffset (MachineInstr &Hi, MachineInstr &Lo,
4141 MachineInstr &TailAdd, Register GSReg);
@@ -142,9 +142,21 @@ bool RISCVMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi,
142142// Update the offset in Hi and Lo instructions.
143143// Delete the tail instruction and update all the uses to use the
144144// output from Lo.
145- void RISCVMergeBaseOffsetOpt::foldOffset (MachineInstr &Hi, MachineInstr &Lo,
145+ bool RISCVMergeBaseOffsetOpt::foldOffset (MachineInstr &Hi, MachineInstr &Lo,
146146 MachineInstr &Tail, int64_t Offset) {
147147 assert (isInt<32 >(Offset) && " Unexpected offset" );
148+
149+ // If Hi is an AUIPC, don't fold the offset if it is outside the bounds of
150+ // the global object. The object may be within 2GB of the PC, but addresses
151+ // outside of the object might not be.
152+ if (Hi.getOpcode () == RISCV::AUIPC && Hi.getOperand (1 ).isGlobal ()) {
153+ const GlobalValue *GV = Hi.getOperand (1 ).getGlobal ();
154+ Type *Ty = GV->getValueType ();
155+ if (!Ty->isSized () || Offset < 0 ||
156+ (uint64_t )Offset > GV->getDataLayout ().getTypeAllocSize (Ty))
157+ return false ;
158+ }
159+
148160 // Put the offset back in Hi and the Lo
149161 Hi.getOperand (1 ).setOffset (Offset);
150162 if (Hi.getOpcode () != RISCV::AUIPC)
@@ -156,6 +168,7 @@ void RISCVMergeBaseOffsetOpt::foldOffset(MachineInstr &Hi, MachineInstr &Lo,
156168 Tail.eraseFromParent ();
157169 LLVM_DEBUG (dbgs () << " Merged offset " << Offset << " into base.\n "
158170 << " " << Hi << " " << Lo;);
171+ return true ;
159172}
160173
161174// Detect patterns for large offsets that are passed into an ADD instruction.
@@ -205,7 +218,8 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi,
205218 // Handle rs1 of ADDI is X0.
206219 if (AddiReg == RISCV::X0) {
207220 LLVM_DEBUG (dbgs () << " Offset Instrs: " << OffsetTail);
208- foldOffset (Hi, Lo, TailAdd, OffLo);
221+ if (!foldOffset (Hi, Lo, TailAdd, OffLo))
222+ return false ;
209223 OffsetTail.eraseFromParent ();
210224 return true ;
211225 }
@@ -226,7 +240,8 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi,
226240 return false ;
227241 LLVM_DEBUG (dbgs () << " Offset Instrs: " << OffsetTail
228242 << " " << OffsetLui);
229- foldOffset (Hi, Lo, TailAdd, Offset);
243+ if (!foldOffset (Hi, Lo, TailAdd, Offset))
244+ return false ;
230245 OffsetTail.eraseFromParent ();
231246 OffsetLui.eraseFromParent ();
232247 return true ;
@@ -235,7 +250,8 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi,
235250 // exists.
236251 LLVM_DEBUG (dbgs () << " Offset Instr: " << OffsetTail);
237252 int64_t Offset = SignExtend64<32 >(OffsetTail.getOperand (1 ).getImm () << 12 );
238- foldOffset (Hi, Lo, TailAdd, Offset);
253+ if (!foldOffset (Hi, Lo, TailAdd, Offset))
254+ return false ;
239255 OffsetTail.eraseFromParent ();
240256 return true ;
241257 }
@@ -294,7 +310,8 @@ bool RISCVMergeBaseOffsetOpt::foldShiftedOffset(MachineInstr &Hi,
294310 Offset = (uint64_t )Offset << ShAmt;
295311
296312 LLVM_DEBUG (dbgs () << " Offset Instr: " << OffsetTail);
297- foldOffset (Hi, Lo, TailShXAdd, Offset);
313+ if (!foldOffset (Hi, Lo, TailShXAdd, Offset))
314+ return false ;
298315 OffsetTail.eraseFromParent ();
299316 return true ;
300317}
@@ -327,15 +344,15 @@ bool RISCVMergeBaseOffsetOpt::detectAndFoldOffset(MachineInstr &Hi,
327344 if (TailTail.getOpcode () == RISCV::ADDI) {
328345 Offset += TailTail.getOperand (2 ).getImm ();
329346 LLVM_DEBUG (dbgs () << " Offset Instrs: " << Tail << TailTail);
330- foldOffset (Hi, Lo, TailTail, Offset);
347+ if (!foldOffset (Hi, Lo, TailTail, Offset))
348+ return false ;
331349 Tail.eraseFromParent ();
332350 return true ;
333351 }
334352 }
335353
336354 LLVM_DEBUG (dbgs () << " Offset Instr: " << Tail);
337- foldOffset (Hi, Lo, Tail, Offset);
338- return true ;
355+ return foldOffset (Hi, Lo, Tail, Offset);
339356 }
340357 case RISCV::ADD:
341358 // The offset is too large to fit in the immediate field of ADDI.
0 commit comments