[llvm] ccbfcfd - [SystemZ] Handle huge immediates in SystemZInstrInfo::loadImmediate().
Jonas Paulsson via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 15 10:09:46 PDT 2021
Author: Jonas Paulsson
Date: 2021-10-15T19:08:45+02:00
New Revision: ccbfcfda1e21f95498ec9b00504b929fcc297a13
URL: https://github.com/llvm/llvm-project/commit/ccbfcfda1e21f95498ec9b00504b929fcc297a13
DIFF: https://github.com/llvm/llvm-project/commit/ccbfcfda1e21f95498ec9b00504b929fcc297a13.diff
LOG: [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
Added:
Modified:
llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
llvm/test/CodeGen/SystemZ/int-const-02.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
index 7a1e2c672e592..b4c5afc5c1a4e 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -1923,7 +1923,7 @@ void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned Reg, uint64_t Value) const {
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
- unsigned Opcode;
+ unsigned Opcode = 0;
if (isInt<16>(Value))
Opcode = SystemZ::LGHI;
else if (SystemZ::isImmLL(Value))
@@ -1931,11 +1931,23 @@ void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB,
else if (SystemZ::isImmLH(Value)) {
Opcode = SystemZ::LLILH;
Value >>= 16;
- } else {
- assert(isInt<32>(Value) && "Huge values not handled yet");
+ }
+ else if (isInt<32>(Value))
Opcode = SystemZ::LGFI;
+ if (Opcode) {
+ BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value);
+ return;
}
- BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value);
+
+ MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
+ assert (MRI.isSSA() && "Huge values only handled before reg-alloc .");
+ Register Reg0 = MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
+ Register Reg1 = MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
+ BuildMI(MBB, MBBI, DL, get(SystemZ::IMPLICIT_DEF), Reg0);
+ BuildMI(MBB, MBBI, DL, get(SystemZ::IIHF64), Reg1)
+ .addReg(Reg0).addImm(Value >> 32);
+ BuildMI(MBB, MBBI, DL, get(SystemZ::IILF64), Reg)
+ .addReg(Reg1).addImm(Value & ((uint64_t(1) << 32) - 1));
}
bool SystemZInstrInfo::verifyInstruction(const MachineInstr &MI,
diff --git a/llvm/test/CodeGen/SystemZ/int-const-02.ll b/llvm/test/CodeGen/SystemZ/int-const-02.ll
index 975fbf8698f29..3310605fe8499 100644
--- a/llvm/test/CodeGen/SystemZ/int-const-02.ll
+++ b/llvm/test/CodeGen/SystemZ/int-const-02.ll
@@ -3,6 +3,7 @@
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
declare void @foo(i64, i64, i64, i64)
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1 immarg)
; Check 0.
define i64 @f1() {
@@ -300,3 +301,28 @@ define i64 @f32(i64 *%ptr) {
ret i64 3944173009226982604
}
+; Check that huge constants can be loaded during isel pseudo expansion. This
+; is the iteration count loaded into a register after dividing by 256.
+define void @f33(i8* %Src, i8* %Dst) {
+; CHECK-LABEL: f33:
+; CHECK: iihf %r0, 1
+; CHECK: iilf %r0, 1
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %Src, i8* %Dst, i64 1099511628032, i1 false)
+ ret void
+}
+
+define void @f34(i8* %Src, i8* %Dst) {
+; CHECK-LABEL: f34:
+; CHECK: iihf %r0, 2
+; CHECK: iilf %r0, 0
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %Src, i8* %Dst, i64 2199023255552, i1 false)
+ ret void
+}
+
+define void @f35(i8* %Src, i8* %Dst) {
+; CHECK-LABEL: f35:
+; CHECK: iihf %r0, 8388607
+; CHECK: iilf %r0, 4294967295
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %Src, i8* %Dst, i64 9223372036854775800, i1 false)
+ ret void
+}
More information about the llvm-commits
mailing list