diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 44ff1d00472..7debcdd506a 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -222,7 +222,8 @@ let neverHasSideEffects = 1 in { } // 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. def LHI : UnaryRI<"lhi", 0xA78, bitconvert, GR32, imm32sx16>; 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 // for 32-bit moves because IILF leaves the upper 32 bits of the // 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 IILF : BinaryRIL<"iilf", 0xC09, insertlf, GR64, imm64lf32>; diff --git a/test/CodeGen/SystemZ/args-01.ll b/test/CodeGen/SystemZ/args-01.ll index a6b80c54db5..50e80031f0e 100644 --- a/test/CodeGen/SystemZ/args-01.ll +++ b/test/CodeGen/SystemZ/args-01.ll @@ -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 ; is hard-coded in the FP128 tests. ; -; The order of the CHECK-INT loads doesn't matter. The same goes for the -; CHECK_FP128-* stores and the CHECK-STACK stores. It would be OK to reorder +; The order of the CHECK-STACK stores doesn't matter. It would be OK to reorder ; them in response to future code changes. define void @foo() { ; CHECK-INT: foo: -; CHECK-INT: lhi %r2, 1 -; CHECK-INT: lhi %r3, 2 -; CHECK-INT: lhi %r4, 3 -; CHECK-INT: lghi %r5, 4 -; CHECK-INT: la %r6, {{224|240}}(%r15) +; CHECK-INT-DAG: lhi %r2, 1 +; CHECK-INT-DAG: lhi %r3, 2 +; CHECK-INT-DAG: lhi %r4, 3 +; CHECK-INT-DAG: lghi %r5, 4 +; CHECK-INT-DAG: la %r6, {{224|240}}(%r15) ; CHECK-INT: brasl %r14, bar@PLT ; ; CHECK-FLOAT: foo: @@ -42,15 +41,15 @@ define void @foo() { ; CHECK-FP128-1: foo: ; CHECK-FP128-1: aghi %r15, -256 ; CHECK-FP128-1: lzxr %f0 -; CHECK-FP128-1: std %f0, 224(%r15) -; CHECK-FP128-1: std %f2, 232(%r15) +; CHECK-FP128-1-DAG: std %f0, 224(%r15) +; CHECK-FP128-1-DAG: std %f2, 232(%r15) ; CHECK-FP128-1: brasl %r14, bar@PLT ; ; CHECK-FP128-2: foo: ; CHECK-FP128-2: aghi %r15, -256 ; CHECK-FP128-2: lzxr %f0 -; CHECK-FP128-2: std %f0, 240(%r15) -; CHECK-FP128-2: std %f2, 248(%r15) +; CHECK-FP128-2-DAG: std %f0, 240(%r15) +; CHECK-FP128-2-DAG: std %f2, 248(%r15) ; CHECK-FP128-2: brasl %r14, bar@PLT ; ; CHECK-STACK: foo: diff --git a/test/CodeGen/SystemZ/args-02.ll b/test/CodeGen/SystemZ/args-02.ll index 9ea111c2e02..b964d516fa1 100644 --- a/test/CodeGen/SystemZ/args-02.ll +++ b/test/CodeGen/SystemZ/args-02.ll @@ -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 ; is hard-coded in the FP128 tests. ; -; The order of the CHECK-INT loads doesn't matter. The same goes for the -; CHECK_FP128-* stores and the CHECK-STACK stores. It would be OK to reorder +; The order of the CHECK-STACK stores doesn't matter. It would be OK to reorder ; them in response to future code changes. define void @foo() { ; CHECK-INT: foo: -; CHECK-INT: lghi %r2, -1 -; CHECK-INT: lghi %r3, -2 -; CHECK-INT: lghi %r4, -3 -; CHECK-INT: lghi %r5, -4 -; CHECK-INT: la %r6, {{224|240}}(%r15) +; CHECK-INT-DAG: lghi %r2, -1 +; CHECK-INT-DAG: lghi %r3, -2 +; CHECK-INT-DAG: lghi %r4, -3 +; CHECK-INT-DAG: lghi %r5, -4 +; CHECK-INT-DAG: la %r6, {{224|240}}(%r15) ; CHECK-INT: brasl %r14, bar@PLT ; ; CHECK-FLOAT: foo: @@ -43,15 +42,15 @@ define void @foo() { ; CHECK-FP128-1: foo: ; CHECK-FP128-1: aghi %r15, -256 ; CHECK-FP128-1: lzxr %f0 -; CHECK-FP128-1: std %f0, 224(%r15) -; CHECK-FP128-1: std %f2, 232(%r15) +; CHECK-FP128-1-DAG: std %f0, 224(%r15) +; CHECK-FP128-1-DAG: std %f2, 232(%r15) ; CHECK-FP128-1: brasl %r14, bar@PLT ; ; CHECK-FP128-2: foo: ; CHECK-FP128-2: aghi %r15, -256 ; CHECK-FP128-2: lzxr %f0 -; CHECK-FP128-2: std %f0, 240(%r15) -; CHECK-FP128-2: std %f2, 248(%r15) +; CHECK-FP128-2-DAG: std %f0, 240(%r15) +; CHECK-FP128-2-DAG: std %f2, 248(%r15) ; CHECK-FP128-2: brasl %r14, bar@PLT ; ; CHECK-STACK: foo: diff --git a/test/CodeGen/SystemZ/args-03.ll b/test/CodeGen/SystemZ/args-03.ll index f954d584fcf..28c33388dc3 100644 --- a/test/CodeGen/SystemZ/args-03.ll +++ b/test/CodeGen/SystemZ/args-03.ll @@ -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 ; is hard-coded in the FP128 tests. ; -; The order of the CHECK-INT loads doesn't matter. The same goes for the -; CHECK_FP128-* stores and the CHECK-STACK stores. It would be OK to reorder +; The order of the CHECK-STACK stores doesn't matter. It would be OK to reorder ; them in response to future code changes. define void @foo() { ; CHECK-INT: foo: -; CHECK-INT: lghi %r2, 255 -; CHECK-INT: llill %r3, 65534 -; CHECK-INT: llilf %r4, 4294967293 -; CHECK-INT: lghi %r5, -4 -; CHECK-INT: la %r6, {{224|240}}(%r15) +; CHECK-INT-DAG: lghi %r2, 255 +; CHECK-INT-DAG: llill %r3, 65534 +; CHECK-INT-DAG: llilf %r4, 4294967293 +; CHECK-INT-DAG: lghi %r5, -4 +; CHECK-INT-DAG: la %r6, {{224|240}}(%r15) ; CHECK-INT: brasl %r14, bar@PLT ; ; CHECK-FLOAT: foo: @@ -43,15 +42,15 @@ define void @foo() { ; CHECK-FP128-1: foo: ; CHECK-FP128-1: aghi %r15, -256 ; CHECK-FP128-1: lzxr %f0 -; CHECK-FP128-1: std %f0, 224(%r15) -; CHECK-FP128-1: std %f2, 232(%r15) +; CHECK-FP128-1-DAG: std %f0, 224(%r15) +; CHECK-FP128-1-DAG: std %f2, 232(%r15) ; CHECK-FP128-1: brasl %r14, bar@PLT ; ; CHECK-FP128-2: foo: ; CHECK-FP128-2: aghi %r15, -256 ; CHECK-FP128-2: lzxr %f0 -; CHECK-FP128-2: std %f0, 240(%r15) -; CHECK-FP128-2: std %f2, 248(%r15) +; CHECK-FP128-2-DAG: std %f0, 240(%r15) +; CHECK-FP128-2-DAG: std %f2, 248(%r15) ; CHECK-FP128-2: brasl %r14, bar@PLT ; ; CHECK-STACK: foo: diff --git a/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll b/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll index 4f7d820adaf..9dca13d15bb 100644 --- a/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll +++ b/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll @@ -156,7 +156,7 @@ define i32 @f12(i32 %dummy, i64 %base, i64 %index, i32 %b) { ret i32 %res } -; Check that constants are forced into a register. +; Check that constants are handled. define i32 @f13(i32 %dummy, i32 *%ptr) { ; CHECK: f13: ; CHECK: lhi [[LIMIT:%r[0-9]+]], 42 @@ -164,7 +164,7 @@ define i32 @f13(i32 %dummy, i32 *%ptr) { ; CHECK: [[LOOP:\.[^:]*]]: ; CHECK: lr [[NEW:%r[0-9]+]], %r2 ; CHECK: crjle %r2, [[LIMIT]], [[KEEP:\..*]] -; CHECK: lr [[NEW]], [[LIMIT]] +; CHECK: lhi [[NEW]], 42 ; CHECK: cs %r2, [[NEW]], 0(%r3) ; CHECK: jlh [[LOOP]] ; CHECK: br %r14 diff --git a/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll b/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll index cd35ab019e0..d6b5dcd482e 100644 --- a/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll +++ b/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll @@ -123,7 +123,7 @@ define i64 @f9(i64 %dummy, i64 %base, i64 %index, i64 %b) { ret i64 %res } -; Check that constants are forced into a register. +; Check that constants are handled. define i64 @f10(i64 %dummy, i64 *%ptr) { ; CHECK: f10: ; CHECK: lghi [[LIMIT:%r[0-9]+]], 42 @@ -131,7 +131,7 @@ define i64 @f10(i64 %dummy, i64 *%ptr) { ; CHECK: [[LOOP:\.[^:]*]]: ; CHECK: lgr [[NEW:%r[0-9]+]], %r2 ; CHECK: cgrjle %r2, [[LIMIT]], [[KEEP:\..*]] -; CHECK: lgr [[NEW]], [[LIMIT]] +; CHECK: lghi [[NEW]], 42 ; CHECK: csg %r2, [[NEW]], 0(%r3) ; CHECK: jlh [[LOOP]] ; CHECK: br %r14 diff --git a/test/CodeGen/SystemZ/int-const-01.ll b/test/CodeGen/SystemZ/int-const-01.ll index a580154e6b5..e714e9d1934 100644 --- a/test/CodeGen/SystemZ/int-const-01.ll +++ b/test/CodeGen/SystemZ/int-const-01.ll @@ -2,6 +2,8 @@ ; ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s +declare void @foo(i32, i32, i32, i32) + ; Check 0. define i32 @f1() { ; CHECK: f1: @@ -89,3 +91,23 @@ define i32 @f11() { ; CHECK: br %r14 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 +} diff --git a/test/CodeGen/SystemZ/int-const-02.ll b/test/CodeGen/SystemZ/int-const-02.ll index b345e3f2a2a..ba143c772d4 100644 --- a/test/CodeGen/SystemZ/int-const-02.ll +++ b/test/CodeGen/SystemZ/int-const-02.ll @@ -2,6 +2,8 @@ ; ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s +declare void @foo(i64, i64, i64, i64) + ; Check 0. define i64 @f1() { ; CHECK: f1: @@ -249,3 +251,35 @@ define i64 @f30() { ; CHECK-NEXT: br %r14 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 +}