Skip to content

Commit ccbfcfd

Browse files
committed
[SystemZ] Handle huge immediates in SystemZInstrInfo::loadImmediate().
This is needed during isel pseudo expansion in order not to crash on huge immediates. Review: Ulrich Weigand
1 parent 6a154e6 commit ccbfcfd

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,19 +1923,31 @@ void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB,
19231923
MachineBasicBlock::iterator MBBI,
19241924
unsigned Reg, uint64_t Value) const {
19251925
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
1926-
unsigned Opcode;
1926+
unsigned Opcode = 0;
19271927
if (isInt<16>(Value))
19281928
Opcode = SystemZ::LGHI;
19291929
else if (SystemZ::isImmLL(Value))
19301930
Opcode = SystemZ::LLILL;
19311931
else if (SystemZ::isImmLH(Value)) {
19321932
Opcode = SystemZ::LLILH;
19331933
Value >>= 16;
1934-
} else {
1935-
assert(isInt<32>(Value) && "Huge values not handled yet");
1934+
}
1935+
else if (isInt<32>(Value))
19361936
Opcode = SystemZ::LGFI;
1937+
if (Opcode) {
1938+
BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value);
1939+
return;
19371940
}
1938-
BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value);
1941+
1942+
MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
1943+
assert (MRI.isSSA() && "Huge values only handled before reg-alloc .");
1944+
Register Reg0 = MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
1945+
Register Reg1 = MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
1946+
BuildMI(MBB, MBBI, DL, get(SystemZ::IMPLICIT_DEF), Reg0);
1947+
BuildMI(MBB, MBBI, DL, get(SystemZ::IIHF64), Reg1)
1948+
.addReg(Reg0).addImm(Value >> 32);
1949+
BuildMI(MBB, MBBI, DL, get(SystemZ::IILF64), Reg)
1950+
.addReg(Reg1).addImm(Value & ((uint64_t(1) << 32) - 1));
19391951
}
19401952

19411953
bool SystemZInstrInfo::verifyInstruction(const MachineInstr &MI,

llvm/test/CodeGen/SystemZ/int-const-02.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
44

55
declare void @foo(i64, i64, i64, i64)
6+
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1 immarg)
67

78
; Check 0.
89
define i64 @f1() {
@@ -300,3 +301,28 @@ define i64 @f32(i64 *%ptr) {
300301
ret i64 3944173009226982604
301302
}
302303

304+
; Check that huge constants can be loaded during isel pseudo expansion. This
305+
; is the iteration count loaded into a register after dividing by 256.
306+
define void @f33(i8* %Src, i8* %Dst) {
307+
; CHECK-LABEL: f33:
308+
; CHECK: iihf %r0, 1
309+
; CHECK: iilf %r0, 1
310+
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %Src, i8* %Dst, i64 1099511628032, i1 false)
311+
ret void
312+
}
313+
314+
define void @f34(i8* %Src, i8* %Dst) {
315+
; CHECK-LABEL: f34:
316+
; CHECK: iihf %r0, 2
317+
; CHECK: iilf %r0, 0
318+
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %Src, i8* %Dst, i64 2199023255552, i1 false)
319+
ret void
320+
}
321+
322+
define void @f35(i8* %Src, i8* %Dst) {
323+
; CHECK-LABEL: f35:
324+
; CHECK: iihf %r0, 8388607
325+
; CHECK: iilf %r0, 4294967295
326+
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %Src, i8* %Dst, i64 9223372036854775800, i1 false)
327+
ret void
328+
}

0 commit comments

Comments
 (0)