mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-10 20:33:15 +00:00
[SystemZ] Allow immediate moves to be rematerialized
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185068 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
722e9e6d0a
commit
a6e12b5756
@ -222,7 +222,8 @@ let neverHasSideEffects = 1 in {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Immediate moves.
|
// Immediate moves.
|
||||||
let neverHasSideEffects = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
|
let neverHasSideEffects = 1, isAsCheapAsAMove = 1, isMoveImm = 1,
|
||||||
|
isReMaterializable = 1 in {
|
||||||
// 16-bit sign-extended immediates.
|
// 16-bit sign-extended immediates.
|
||||||
def LHI : UnaryRI<"lhi", 0xA78, bitconvert, GR32, imm32sx16>;
|
def LHI : UnaryRI<"lhi", 0xA78, bitconvert, GR32, imm32sx16>;
|
||||||
def LGHI : UnaryRI<"lghi", 0xA79, bitconvert, GR64, imm64sx16>;
|
def LGHI : UnaryRI<"lghi", 0xA79, bitconvert, GR64, imm64sx16>;
|
||||||
@ -476,7 +477,8 @@ def IIHH : BinaryRI<"iihh", 0xA50, inserthh, GR64, imm64hh16>;
|
|||||||
// full-width move. (We use IILF rather than something like LLILF
|
// full-width move. (We use IILF rather than something like LLILF
|
||||||
// for 32-bit moves because IILF leaves the upper 32 bits of the
|
// for 32-bit moves because IILF leaves the upper 32 bits of the
|
||||||
// GR64 unchanged.)
|
// GR64 unchanged.)
|
||||||
let isCodeGenOnly = 1 in {
|
let isCodeGenOnly = 1, isAsCheapAsAMove = 1, isMoveImm = 1,
|
||||||
|
isReMaterializable = 1 in {
|
||||||
def IILF32 : UnaryRIL<"iilf", 0xC09, bitconvert, GR32, uimm32>;
|
def IILF32 : UnaryRIL<"iilf", 0xC09, bitconvert, GR32, uimm32>;
|
||||||
}
|
}
|
||||||
def IILF : BinaryRIL<"iilf", 0xC09, insertlf, GR64, imm64lf32>;
|
def IILF : BinaryRIL<"iilf", 0xC09, insertlf, GR64, imm64lf32>;
|
||||||
|
@ -17,16 +17,15 @@ declare void @bar(i8, i16, i32, i64, float, double, fp128, i64,
|
|||||||
; normally use %f0/%f2 as the first available 128-bit pair. This choice
|
; normally use %f0/%f2 as the first available 128-bit pair. This choice
|
||||||
; is hard-coded in the FP128 tests.
|
; is hard-coded in the FP128 tests.
|
||||||
;
|
;
|
||||||
; The order of the CHECK-INT loads doesn't matter. The same goes for the
|
; The order of the CHECK-STACK stores doesn't matter. It would be OK to reorder
|
||||||
; CHECK_FP128-* stores and the CHECK-STACK stores. It would be OK to reorder
|
|
||||||
; them in response to future code changes.
|
; them in response to future code changes.
|
||||||
define void @foo() {
|
define void @foo() {
|
||||||
; CHECK-INT: foo:
|
; CHECK-INT: foo:
|
||||||
; CHECK-INT: lhi %r2, 1
|
; CHECK-INT-DAG: lhi %r2, 1
|
||||||
; CHECK-INT: lhi %r3, 2
|
; CHECK-INT-DAG: lhi %r3, 2
|
||||||
; CHECK-INT: lhi %r4, 3
|
; CHECK-INT-DAG: lhi %r4, 3
|
||||||
; CHECK-INT: lghi %r5, 4
|
; CHECK-INT-DAG: lghi %r5, 4
|
||||||
; CHECK-INT: la %r6, {{224|240}}(%r15)
|
; CHECK-INT-DAG: la %r6, {{224|240}}(%r15)
|
||||||
; CHECK-INT: brasl %r14, bar@PLT
|
; CHECK-INT: brasl %r14, bar@PLT
|
||||||
;
|
;
|
||||||
; CHECK-FLOAT: foo:
|
; CHECK-FLOAT: foo:
|
||||||
@ -42,15 +41,15 @@ define void @foo() {
|
|||||||
; CHECK-FP128-1: foo:
|
; CHECK-FP128-1: foo:
|
||||||
; CHECK-FP128-1: aghi %r15, -256
|
; CHECK-FP128-1: aghi %r15, -256
|
||||||
; CHECK-FP128-1: lzxr %f0
|
; CHECK-FP128-1: lzxr %f0
|
||||||
; CHECK-FP128-1: std %f0, 224(%r15)
|
; CHECK-FP128-1-DAG: std %f0, 224(%r15)
|
||||||
; CHECK-FP128-1: std %f2, 232(%r15)
|
; CHECK-FP128-1-DAG: std %f2, 232(%r15)
|
||||||
; CHECK-FP128-1: brasl %r14, bar@PLT
|
; CHECK-FP128-1: brasl %r14, bar@PLT
|
||||||
;
|
;
|
||||||
; CHECK-FP128-2: foo:
|
; CHECK-FP128-2: foo:
|
||||||
; CHECK-FP128-2: aghi %r15, -256
|
; CHECK-FP128-2: aghi %r15, -256
|
||||||
; CHECK-FP128-2: lzxr %f0
|
; CHECK-FP128-2: lzxr %f0
|
||||||
; CHECK-FP128-2: std %f0, 240(%r15)
|
; CHECK-FP128-2-DAG: std %f0, 240(%r15)
|
||||||
; CHECK-FP128-2: std %f2, 248(%r15)
|
; CHECK-FP128-2-DAG: std %f2, 248(%r15)
|
||||||
; CHECK-FP128-2: brasl %r14, bar@PLT
|
; CHECK-FP128-2: brasl %r14, bar@PLT
|
||||||
;
|
;
|
||||||
; CHECK-STACK: foo:
|
; CHECK-STACK: foo:
|
||||||
|
@ -18,16 +18,15 @@ declare void @bar(i8 signext, i16 signext, i32 signext, i64, float, double,
|
|||||||
; normally use %f0/%f2 as the first available 128-bit pair. This choice
|
; normally use %f0/%f2 as the first available 128-bit pair. This choice
|
||||||
; is hard-coded in the FP128 tests.
|
; is hard-coded in the FP128 tests.
|
||||||
;
|
;
|
||||||
; The order of the CHECK-INT loads doesn't matter. The same goes for the
|
; The order of the CHECK-STACK stores doesn't matter. It would be OK to reorder
|
||||||
; CHECK_FP128-* stores and the CHECK-STACK stores. It would be OK to reorder
|
|
||||||
; them in response to future code changes.
|
; them in response to future code changes.
|
||||||
define void @foo() {
|
define void @foo() {
|
||||||
; CHECK-INT: foo:
|
; CHECK-INT: foo:
|
||||||
; CHECK-INT: lghi %r2, -1
|
; CHECK-INT-DAG: lghi %r2, -1
|
||||||
; CHECK-INT: lghi %r3, -2
|
; CHECK-INT-DAG: lghi %r3, -2
|
||||||
; CHECK-INT: lghi %r4, -3
|
; CHECK-INT-DAG: lghi %r4, -3
|
||||||
; CHECK-INT: lghi %r5, -4
|
; CHECK-INT-DAG: lghi %r5, -4
|
||||||
; CHECK-INT: la %r6, {{224|240}}(%r15)
|
; CHECK-INT-DAG: la %r6, {{224|240}}(%r15)
|
||||||
; CHECK-INT: brasl %r14, bar@PLT
|
; CHECK-INT: brasl %r14, bar@PLT
|
||||||
;
|
;
|
||||||
; CHECK-FLOAT: foo:
|
; CHECK-FLOAT: foo:
|
||||||
@ -43,15 +42,15 @@ define void @foo() {
|
|||||||
; CHECK-FP128-1: foo:
|
; CHECK-FP128-1: foo:
|
||||||
; CHECK-FP128-1: aghi %r15, -256
|
; CHECK-FP128-1: aghi %r15, -256
|
||||||
; CHECK-FP128-1: lzxr %f0
|
; CHECK-FP128-1: lzxr %f0
|
||||||
; CHECK-FP128-1: std %f0, 224(%r15)
|
; CHECK-FP128-1-DAG: std %f0, 224(%r15)
|
||||||
; CHECK-FP128-1: std %f2, 232(%r15)
|
; CHECK-FP128-1-DAG: std %f2, 232(%r15)
|
||||||
; CHECK-FP128-1: brasl %r14, bar@PLT
|
; CHECK-FP128-1: brasl %r14, bar@PLT
|
||||||
;
|
;
|
||||||
; CHECK-FP128-2: foo:
|
; CHECK-FP128-2: foo:
|
||||||
; CHECK-FP128-2: aghi %r15, -256
|
; CHECK-FP128-2: aghi %r15, -256
|
||||||
; CHECK-FP128-2: lzxr %f0
|
; CHECK-FP128-2: lzxr %f0
|
||||||
; CHECK-FP128-2: std %f0, 240(%r15)
|
; CHECK-FP128-2-DAG: std %f0, 240(%r15)
|
||||||
; CHECK-FP128-2: std %f2, 248(%r15)
|
; CHECK-FP128-2-DAG: std %f2, 248(%r15)
|
||||||
; CHECK-FP128-2: brasl %r14, bar@PLT
|
; CHECK-FP128-2: brasl %r14, bar@PLT
|
||||||
;
|
;
|
||||||
; CHECK-STACK: foo:
|
; CHECK-STACK: foo:
|
||||||
|
@ -18,16 +18,15 @@ declare void @bar(i8 zeroext, i16 zeroext, i32 zeroext, i64, float, double,
|
|||||||
; normally use %f0/%f2 as the first available 128-bit pair. This choice
|
; normally use %f0/%f2 as the first available 128-bit pair. This choice
|
||||||
; is hard-coded in the FP128 tests.
|
; is hard-coded in the FP128 tests.
|
||||||
;
|
;
|
||||||
; The order of the CHECK-INT loads doesn't matter. The same goes for the
|
; The order of the CHECK-STACK stores doesn't matter. It would be OK to reorder
|
||||||
; CHECK_FP128-* stores and the CHECK-STACK stores. It would be OK to reorder
|
|
||||||
; them in response to future code changes.
|
; them in response to future code changes.
|
||||||
define void @foo() {
|
define void @foo() {
|
||||||
; CHECK-INT: foo:
|
; CHECK-INT: foo:
|
||||||
; CHECK-INT: lghi %r2, 255
|
; CHECK-INT-DAG: lghi %r2, 255
|
||||||
; CHECK-INT: llill %r3, 65534
|
; CHECK-INT-DAG: llill %r3, 65534
|
||||||
; CHECK-INT: llilf %r4, 4294967293
|
; CHECK-INT-DAG: llilf %r4, 4294967293
|
||||||
; CHECK-INT: lghi %r5, -4
|
; CHECK-INT-DAG: lghi %r5, -4
|
||||||
; CHECK-INT: la %r6, {{224|240}}(%r15)
|
; CHECK-INT-DAG: la %r6, {{224|240}}(%r15)
|
||||||
; CHECK-INT: brasl %r14, bar@PLT
|
; CHECK-INT: brasl %r14, bar@PLT
|
||||||
;
|
;
|
||||||
; CHECK-FLOAT: foo:
|
; CHECK-FLOAT: foo:
|
||||||
@ -43,15 +42,15 @@ define void @foo() {
|
|||||||
; CHECK-FP128-1: foo:
|
; CHECK-FP128-1: foo:
|
||||||
; CHECK-FP128-1: aghi %r15, -256
|
; CHECK-FP128-1: aghi %r15, -256
|
||||||
; CHECK-FP128-1: lzxr %f0
|
; CHECK-FP128-1: lzxr %f0
|
||||||
; CHECK-FP128-1: std %f0, 224(%r15)
|
; CHECK-FP128-1-DAG: std %f0, 224(%r15)
|
||||||
; CHECK-FP128-1: std %f2, 232(%r15)
|
; CHECK-FP128-1-DAG: std %f2, 232(%r15)
|
||||||
; CHECK-FP128-1: brasl %r14, bar@PLT
|
; CHECK-FP128-1: brasl %r14, bar@PLT
|
||||||
;
|
;
|
||||||
; CHECK-FP128-2: foo:
|
; CHECK-FP128-2: foo:
|
||||||
; CHECK-FP128-2: aghi %r15, -256
|
; CHECK-FP128-2: aghi %r15, -256
|
||||||
; CHECK-FP128-2: lzxr %f0
|
; CHECK-FP128-2: lzxr %f0
|
||||||
; CHECK-FP128-2: std %f0, 240(%r15)
|
; CHECK-FP128-2-DAG: std %f0, 240(%r15)
|
||||||
; CHECK-FP128-2: std %f2, 248(%r15)
|
; CHECK-FP128-2-DAG: std %f2, 248(%r15)
|
||||||
; CHECK-FP128-2: brasl %r14, bar@PLT
|
; CHECK-FP128-2: brasl %r14, bar@PLT
|
||||||
;
|
;
|
||||||
; CHECK-STACK: foo:
|
; CHECK-STACK: foo:
|
||||||
|
@ -156,7 +156,7 @@ define i32 @f12(i32 %dummy, i64 %base, i64 %index, i32 %b) {
|
|||||||
ret i32 %res
|
ret i32 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
; Check that constants are forced into a register.
|
; Check that constants are handled.
|
||||||
define i32 @f13(i32 %dummy, i32 *%ptr) {
|
define i32 @f13(i32 %dummy, i32 *%ptr) {
|
||||||
; CHECK: f13:
|
; CHECK: f13:
|
||||||
; CHECK: lhi [[LIMIT:%r[0-9]+]], 42
|
; CHECK: lhi [[LIMIT:%r[0-9]+]], 42
|
||||||
@ -164,7 +164,7 @@ define i32 @f13(i32 %dummy, i32 *%ptr) {
|
|||||||
; CHECK: [[LOOP:\.[^:]*]]:
|
; CHECK: [[LOOP:\.[^:]*]]:
|
||||||
; CHECK: lr [[NEW:%r[0-9]+]], %r2
|
; CHECK: lr [[NEW:%r[0-9]+]], %r2
|
||||||
; CHECK: crjle %r2, [[LIMIT]], [[KEEP:\..*]]
|
; CHECK: crjle %r2, [[LIMIT]], [[KEEP:\..*]]
|
||||||
; CHECK: lr [[NEW]], [[LIMIT]]
|
; CHECK: lhi [[NEW]], 42
|
||||||
; CHECK: cs %r2, [[NEW]], 0(%r3)
|
; CHECK: cs %r2, [[NEW]], 0(%r3)
|
||||||
; CHECK: jlh [[LOOP]]
|
; CHECK: jlh [[LOOP]]
|
||||||
; CHECK: br %r14
|
; CHECK: br %r14
|
||||||
|
@ -123,7 +123,7 @@ define i64 @f9(i64 %dummy, i64 %base, i64 %index, i64 %b) {
|
|||||||
ret i64 %res
|
ret i64 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
; Check that constants are forced into a register.
|
; Check that constants are handled.
|
||||||
define i64 @f10(i64 %dummy, i64 *%ptr) {
|
define i64 @f10(i64 %dummy, i64 *%ptr) {
|
||||||
; CHECK: f10:
|
; CHECK: f10:
|
||||||
; CHECK: lghi [[LIMIT:%r[0-9]+]], 42
|
; CHECK: lghi [[LIMIT:%r[0-9]+]], 42
|
||||||
@ -131,7 +131,7 @@ define i64 @f10(i64 %dummy, i64 *%ptr) {
|
|||||||
; CHECK: [[LOOP:\.[^:]*]]:
|
; CHECK: [[LOOP:\.[^:]*]]:
|
||||||
; CHECK: lgr [[NEW:%r[0-9]+]], %r2
|
; CHECK: lgr [[NEW:%r[0-9]+]], %r2
|
||||||
; CHECK: cgrjle %r2, [[LIMIT]], [[KEEP:\..*]]
|
; CHECK: cgrjle %r2, [[LIMIT]], [[KEEP:\..*]]
|
||||||
; CHECK: lgr [[NEW]], [[LIMIT]]
|
; CHECK: lghi [[NEW]], 42
|
||||||
; CHECK: csg %r2, [[NEW]], 0(%r3)
|
; CHECK: csg %r2, [[NEW]], 0(%r3)
|
||||||
; CHECK: jlh [[LOOP]]
|
; CHECK: jlh [[LOOP]]
|
||||||
; CHECK: br %r14
|
; CHECK: br %r14
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
;
|
;
|
||||||
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
|
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
|
||||||
|
|
||||||
|
declare void @foo(i32, i32, i32, i32)
|
||||||
|
|
||||||
; Check 0.
|
; Check 0.
|
||||||
define i32 @f1() {
|
define i32 @f1() {
|
||||||
; CHECK: f1:
|
; CHECK: f1:
|
||||||
@ -89,3 +91,23 @@ define i32 @f11() {
|
|||||||
; CHECK: br %r14
|
; CHECK: br %r14
|
||||||
ret i32 -1
|
ret i32 -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Check that constant loads are rematerialized.
|
||||||
|
define i32 @f12() {
|
||||||
|
; CHECK: f12:
|
||||||
|
; CHECK-DAG: lhi %r2, 42
|
||||||
|
; CHECK-DAG: llill %r3, 32768
|
||||||
|
; CHECK-DAG: llilh %r4, 1
|
||||||
|
; CHECK-DAG: iilf %r5, 65537
|
||||||
|
; CHECK: brasl %r14, foo@PLT
|
||||||
|
; CHECK-DAG: lhi %r2, 42
|
||||||
|
; CHECK-DAG: llill %r3, 32768
|
||||||
|
; CHECK-DAG: llilh %r4, 1
|
||||||
|
; CHECK-DAG: iilf %r5, 65537
|
||||||
|
; CHECK: brasl %r14, foo@PLT
|
||||||
|
; CHECK: lhi %r2, 42
|
||||||
|
; CHECK: br %r14
|
||||||
|
call void @foo(i32 42, i32 32768, i32 65536, i32 65537)
|
||||||
|
call void @foo(i32 42, i32 32768, i32 65536, i32 65537)
|
||||||
|
ret i32 42
|
||||||
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
;
|
;
|
||||||
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
|
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
|
||||||
|
|
||||||
|
declare void @foo(i64, i64, i64, i64)
|
||||||
|
|
||||||
; Check 0.
|
; Check 0.
|
||||||
define i64 @f1() {
|
define i64 @f1() {
|
||||||
; CHECK: f1:
|
; CHECK: f1:
|
||||||
@ -249,3 +251,35 @@ define i64 @f30() {
|
|||||||
; CHECK-NEXT: br %r14
|
; CHECK-NEXT: br %r14
|
||||||
ret i64 -2147483649
|
ret i64 -2147483649
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Check that constant loads are rematerialized.
|
||||||
|
define i64 @f31() {
|
||||||
|
; CHECK: f31:
|
||||||
|
; CHECK-DAG: lghi %r2, 42
|
||||||
|
; CHECK-DAG: lgfi %r3, 65537
|
||||||
|
; CHECK-DAG: llilf %r4, 2147483649
|
||||||
|
; CHECK-DAG: llihf %r5, 65537
|
||||||
|
; CHECK: brasl %r14, foo@PLT
|
||||||
|
; CHECK-DAG: llill %r2, 32768
|
||||||
|
; CHECK-DAG: llilh %r3, 1
|
||||||
|
; CHECK-DAG: llihl %r4, 1
|
||||||
|
; CHECK-DAG: llihh %r5, 1
|
||||||
|
; CHECK: brasl %r14, foo@PLT
|
||||||
|
; CHECK-DAG: lghi %r2, 42
|
||||||
|
; CHECK-DAG: lgfi %r3, 65537
|
||||||
|
; CHECK-DAG: llilf %r4, 2147483649
|
||||||
|
; CHECK-DAG: llihf %r5, 65537
|
||||||
|
; CHECK: brasl %r14, foo@PLT
|
||||||
|
; CHECK-DAG: llill %r2, 32768
|
||||||
|
; CHECK-DAG: llilh %r3, 1
|
||||||
|
; CHECK-DAG: llihl %r4, 1
|
||||||
|
; CHECK-DAG: llihh %r5, 1
|
||||||
|
; CHECK: brasl %r14, foo@PLT
|
||||||
|
; CHECK: lghi %r2, 42
|
||||||
|
; CHECK: br %r14
|
||||||
|
call void @foo(i64 42, i64 65537, i64 2147483649, i64 281479271677952)
|
||||||
|
call void @foo(i64 32768, i64 65536, i64 4294967296, i64 281474976710656)
|
||||||
|
call void @foo(i64 42, i64 65537, i64 2147483649, i64 281479271677952)
|
||||||
|
call void @foo(i64 32768, i64 65536, i64 4294967296, i64 281474976710656)
|
||||||
|
ret i64 42
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user