|  | ; Test loading of 64-bit constants. | 
|  | ; | 
|  | ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s | 
|  |  | 
|  | declare void @foo(i64, i64, i64, i64) | 
|  |  | 
|  | ; Check 0. | 
|  | define i64 @f1() { | 
|  | ; CHECK-LABEL: f1: | 
|  | ; CHECK: lghi %r2, 0 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 0 | 
|  | } | 
|  |  | 
|  | ; Check the high end of the LGHI range. | 
|  | define i64 @f2() { | 
|  | ; CHECK-LABEL: f2: | 
|  | ; CHECK: lghi %r2, 32767 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 32767 | 
|  | } | 
|  |  | 
|  | ; Check the next value up, which must use LLILL instead. | 
|  | define i64 @f3() { | 
|  | ; CHECK-LABEL: f3: | 
|  | ; CHECK: llill %r2, 32768 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 32768 | 
|  | } | 
|  |  | 
|  | ; Check the high end of the LLILL range. | 
|  | define i64 @f4() { | 
|  | ; CHECK-LABEL: f4: | 
|  | ; CHECK: llill %r2, 65535 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 65535 | 
|  | } | 
|  |  | 
|  | ; Check the first useful LLILH value, which is the next one up. | 
|  | define i64 @f5() { | 
|  | ; CHECK-LABEL: f5: | 
|  | ; CHECK: llilh %r2, 1 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 65536 | 
|  | } | 
|  |  | 
|  | ; Check the first useful LGFI value, which is the next one up again. | 
|  | define i64 @f6() { | 
|  | ; CHECK-LABEL: f6: | 
|  | ; CHECK: lgfi %r2, 65537 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 65537 | 
|  | } | 
|  |  | 
|  | ; Check the high end of the LGFI range. | 
|  | define i64 @f7() { | 
|  | ; CHECK-LABEL: f7: | 
|  | ; CHECK: lgfi %r2, 2147483647 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 2147483647 | 
|  | } | 
|  |  | 
|  | ; Check the next value up, which should use LLILH instead. | 
|  | define i64 @f8() { | 
|  | ; CHECK-LABEL: f8: | 
|  | ; CHECK: llilh %r2, 32768 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 2147483648 | 
|  | } | 
|  |  | 
|  | ; Check the next value up again, which should use LLILF. | 
|  | define i64 @f9() { | 
|  | ; CHECK-LABEL: f9: | 
|  | ; CHECK: llilf %r2, 2147483649 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 2147483649 | 
|  | } | 
|  |  | 
|  | ; Check the high end of the LLILH range. | 
|  | define i64 @f10() { | 
|  | ; CHECK-LABEL: f10: | 
|  | ; CHECK: llilh %r2, 65535 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 4294901760 | 
|  | } | 
|  |  | 
|  | ; Check the next value up, which must use LLILF. | 
|  | define i64 @f11() { | 
|  | ; CHECK-LABEL: f11: | 
|  | ; CHECK: llilf %r2, 4294901761 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 4294901761 | 
|  | } | 
|  |  | 
|  | ; Check the high end of the LLILF range. | 
|  | define i64 @f12() { | 
|  | ; CHECK-LABEL: f12: | 
|  | ; CHECK: llilf %r2, 4294967295 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 4294967295 | 
|  | } | 
|  |  | 
|  | ; Check the lowest useful LLIHL value, which is the next one up. | 
|  | define i64 @f13() { | 
|  | ; CHECK-LABEL: f13: | 
|  | ; CHECK: llihl %r2, 1 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 4294967296 | 
|  | } | 
|  |  | 
|  | ; Check the next value up, which must use a combination of two instructions. | 
|  | define i64 @f14() { | 
|  | ; CHECK-LABEL: f14: | 
|  | ; CHECK: llihl %r2, 1 | 
|  | ; CHECK-NEXT: oill %r2, 1 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 4294967297 | 
|  | } | 
|  |  | 
|  | ; Check the high end of the OILL range. | 
|  | define i64 @f15() { | 
|  | ; CHECK-LABEL: f15: | 
|  | ; CHECK: llihl %r2, 1 | 
|  | ; CHECK-NEXT: oill %r2, 65535 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 4295032831 | 
|  | } | 
|  |  | 
|  | ; Check the next value up, which should use OILH instead. | 
|  | define i64 @f16() { | 
|  | ; CHECK-LABEL: f16: | 
|  | ; CHECK: llihl %r2, 1 | 
|  | ; CHECK-NEXT: oilh %r2, 1 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 4295032832 | 
|  | } | 
|  |  | 
|  | ; Check the next value up again, which should use OILF. | 
|  | define i64 @f17() { | 
|  | ; CHECK-LABEL: f17: | 
|  | ; CHECK: llihl %r2, 1 | 
|  | ; CHECK-NEXT: oilf %r2, 65537 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 4295032833 | 
|  | } | 
|  |  | 
|  | ; Check the high end of the OILH range. | 
|  | define i64 @f18() { | 
|  | ; CHECK-LABEL: f18: | 
|  | ; CHECK: llihl %r2, 1 | 
|  | ; CHECK-NEXT: oilh %r2, 65535 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 8589869056 | 
|  | } | 
|  |  | 
|  | ; Check the high end of the OILF range. | 
|  | define i64 @f19() { | 
|  | ; CHECK-LABEL: f19: | 
|  | ; CHECK: llihl %r2, 1 | 
|  | ; CHECK-NEXT: oilf %r2, 4294967295 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 8589934591 | 
|  | } | 
|  |  | 
|  | ; Check the high end of the LLIHL range. | 
|  | define i64 @f20() { | 
|  | ; CHECK-LABEL: f20: | 
|  | ; CHECK: llihl %r2, 65535 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 281470681743360 | 
|  | } | 
|  |  | 
|  | ; Check the lowest useful LLIHH value, which is 1<<32 greater than the above. | 
|  | define i64 @f21() { | 
|  | ; CHECK-LABEL: f21: | 
|  | ; CHECK: llihh %r2, 1 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 281474976710656 | 
|  | } | 
|  |  | 
|  | ; Check the lowest useful LLIHF value, which is 1<<32 greater again. | 
|  | define i64 @f22() { | 
|  | ; CHECK-LABEL: f22: | 
|  | ; CHECK: llihf %r2, 65537 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 281479271677952 | 
|  | } | 
|  |  | 
|  | ; Check the highest end of the LLIHH range. | 
|  | define i64 @f23() { | 
|  | ; CHECK-LABEL: f23: | 
|  | ; CHECK: llihh %r2, 65535 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 -281474976710656 | 
|  | } | 
|  |  | 
|  | ; Check the next value up, which must use OILL too. | 
|  | define i64 @f24() { | 
|  | ; CHECK-LABEL: f24: | 
|  | ; CHECK: llihh %r2, 65535 | 
|  | ; CHECK-NEXT: oill %r2, 1 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 -281474976710655 | 
|  | } | 
|  |  | 
|  | ; Check the high end of the LLIHF range. | 
|  | define i64 @f25() { | 
|  | ; CHECK-LABEL: f25: | 
|  | ; CHECK: llihf %r2, 4294967295 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 -4294967296 | 
|  | } | 
|  |  | 
|  | ; Check -1. | 
|  | define i64 @f26() { | 
|  | ; CHECK-LABEL: f26: | 
|  | ; CHECK: lghi %r2, -1 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 -1 | 
|  | } | 
|  |  | 
|  | ; Check the low end of the LGHI range. | 
|  | define i64 @f27() { | 
|  | ; CHECK-LABEL: f27: | 
|  | ; CHECK: lghi %r2, -32768 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 -32768 | 
|  | } | 
|  |  | 
|  | ; Check the next value down, which must use LGFI instead. | 
|  | define i64 @f28() { | 
|  | ; CHECK-LABEL: f28: | 
|  | ; CHECK: lgfi %r2, -32769 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 -32769 | 
|  | } | 
|  |  | 
|  | ; Check the low end of the LGFI range. | 
|  | define i64 @f29() { | 
|  | ; CHECK-LABEL: f29: | 
|  | ; CHECK: lgfi %r2, -2147483648 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 -2147483648 | 
|  | } | 
|  |  | 
|  | ; Check the next value down, which needs a two-instruction sequence. | 
|  | define i64 @f30() { | 
|  | ; CHECK-LABEL: f30: | 
|  | ; CHECK: llihf %r2, 4294967295 | 
|  | ; CHECK-NEXT: oilf %r2, 2147483647 | 
|  | ; CHECK-NEXT: br %r14 | 
|  | ret i64 -2147483649 | 
|  | } | 
|  |  | 
|  | ; Check that constant loads are rematerialized. | 
|  | define i64 @f31() { | 
|  | ; CHECK-LABEL: 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 | 
|  | } | 
|  |  | 
|  | ; Verify that we do not crash on OR with two constant inputs | 
|  | ; (this was PR34859). | 
|  | define i64 @f32(i64 *%ptr) { | 
|  | ; CHECK-LABEL: f32: | 
|  | ; CHECK: llihf %r1, 918324340 | 
|  | ; CHECK: oilf %r1, 1806197964 | 
|  | ; CHECK: la %r0, 1(%r1) | 
|  | store i64 -1, i64* %ptr, align 8 | 
|  | %1 = load i64, i64* %ptr, align 8 | 
|  | %2 = icmp ne i64 %1, 0 | 
|  | %3 = zext i1 %2 to i64 | 
|  | %4 = or i64 %3, 3944173009226982604 | 
|  | store i64 %4, i64* %ptr, align 8 | 
|  | ret i64 3944173009226982604 | 
|  | } | 
|  |  |