1 ; Test insertions of i32s into the low half of an i64.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5 ; Insertion of an i32 can be done using LR.
6 define i64 @f1(i64 %a, i32 %b) {
8 ; CHECK-NOT: {{%r[23]}}
11 %low = zext i32 %b to i64
12 %high = and i64 %a, -4294967296
13 %res = or i64 %high, %low
17 ; ... and again with the operands reversed.
18 define i64 @f2(i64 %a, i32 %b) {
20 ; CHECK-NOT: {{%r[23]}}
23 %low = zext i32 %b to i64
24 %high = and i64 %a, -4294967296
25 %res = or i64 %low, %high
29 ; Like f1, but with "in register" zero extension.
30 define i64 @f3(i64 %a, i64 %b) {
32 ; CHECK-NOT: {{%r[23]}}
35 %low = and i64 %b, 4294967295
36 %high = and i64 %a, -4294967296
37 %res = or i64 %high, %low
41 ; ... and again with the operands reversed.
42 define i64 @f4(i64 %a, i64 %b) {
44 ; CHECK-NOT: {{%r[23]}}
47 %low = and i64 %b, 4294967295
48 %high = and i64 %a, -4294967296
49 %res = or i64 %low, %high
53 ; Unary operations can be done directly into the low half.
54 define i64 @f5(i64 %a, i32 %b) {
56 ; CHECK-NOT: {{%r[23]}}
60 %low = zext i32 %neg to i64
61 %high = and i64 %a, -4294967296
62 %res = or i64 %high, %low
66 ; ...likewise three-operand binary operations like RLL.
67 define i64 @f6(i64 %a, i32 %b) {
69 ; CHECK-NOT: {{%r[23]}}
70 ; CHECK: rll %r2, %r3, 1
72 %parta = shl i32 %b, 1
73 %partb = lshr i32 %b, 31
74 %rot = or i32 %parta, %partb
75 %low = zext i32 %rot to i64
76 %high = and i64 %a, -4294967296
77 %res = or i64 %low, %high
81 ; Loads can be done directly into the low half. The range of L is checked
83 define i64 @f7(i64 %a, i32 *%src) {
85 ; CHECK-NOT: {{%r[23]}}
86 ; CHECK: l %r2, 0(%r3)
88 %b = load i32, i32 *%src
89 %low = zext i32 %b to i64
90 %high = and i64 %a, -4294967296
91 %res = or i64 %high, %low
95 ; ...likewise extending loads.
96 define i64 @f8(i64 %a, i8 *%src) {
98 ; CHECK-NOT: {{%r[23]}}
99 ; CHECK: lb %r2, 0(%r3)
101 %byte = load i8, i8 *%src
102 %b = sext i8 %byte to i32
103 %low = zext i32 %b to i64
104 %high = and i64 %a, -4294967296
105 %res = or i64 %high, %low
109 ; Check a case like f1 in which there is no AND. We simply know from context
110 ; that the upper half of one OR operand and the lower half of the other are
112 define i64 @f9(i64 %a, i32 %b) {
114 ; CHECK: sllg %r2, %r2, 32
117 %shift = shl i64 %a, 32
118 %low = zext i32 %b to i64
119 %or = or i64 %shift, %low
123 ; ...and again with the operands reversed.
124 define i64 @f10(i64 %a, i32 %b) {
126 ; CHECK: sllg %r2, %r2, 32
129 %shift = shl i64 %a, 32
130 %low = zext i32 %b to i64
131 %or = or i64 %low, %shift
135 ; Like f9, but with "in register" zero extension.
136 define i64 @f11(i64 %a, i64 %b) {
140 %shift = shl i64 %a, 32
141 %low = and i64 %b, 4294967295
142 %or = or i64 %shift, %low
146 ; ...and again with the operands reversed.
147 define i64 @f12(i64 %a, i64 %b) {
151 %shift = shl i64 %a, 32
152 %low = and i64 %b, 4294967295
153 %or = or i64 %low, %shift
157 ; Like f9, but for larger shifts than 32.
158 define i64 @f13(i64 %a, i32 %b) {
160 ; CHECK: sllg %r2, %r2, 60
163 %shift = shl i64 %a, 60
164 %low = zext i32 %b to i64
165 %or = or i64 %shift, %low
169 ; We previously wrongly removed the upper AND as dead.
170 define i64 @f14(i64 %a, i64 %b) {
172 ; CHECK: risbg {{%r[0-5]}}, %r2, 6, 134, 0
174 %and1 = and i64 %a, 144115188075855872
175 %and2 = and i64 %b, 15
176 %or = or i64 %and1, %and2
177 %res = icmp eq i64 %or, 0
178 %ext = sext i1 %res to i64
182 ; Check another representation of f8.
183 define i64 @f15(i64 %a, i8 *%src) {
185 ; CHECK-NOT: {{%r[23]}}
186 ; CHECK: lb %r2, 0(%r3)
188 %byte = load i8, i8 *%src
189 %b = sext i8 %byte to i64
190 %low = and i64 %b, 4294967295
191 %high = and i64 %a, -4294967296
192 %res = or i64 %high, %low