[SystemZ] Use LOAD AND TEST for comparisons with -0
[oota-llvm.git] / test / CodeGen / SystemZ / insert-06.ll
1 ; Test insertions of i32s into the low half of an i64.
2 ;
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5 ; Insertion of an i32 can be done using LR.
6 define i64 @f1(i64 %a, i32 %b) {
7 ; CHECK-LABEL: f1:
8 ; CHECK-NOT: {{%r[23]}}
9 ; CHECK: lr %r2, %r3
10 ; CHECK: br %r14
11   %low = zext i32 %b to i64
12   %high = and i64 %a, -4294967296
13   %res = or i64 %high, %low
14   ret i64 %res
15 }
16
17 ; ... and again with the operands reversed.
18 define i64 @f2(i64 %a, i32 %b) {
19 ; CHECK-LABEL: f2:
20 ; CHECK-NOT: {{%r[23]}}
21 ; CHECK: lr %r2, %r3
22 ; CHECK: br %r14
23   %low = zext i32 %b to i64
24   %high = and i64 %a, -4294967296
25   %res = or i64 %low, %high
26   ret i64 %res
27 }
28
29 ; Like f1, but with "in register" zero extension.
30 define i64 @f3(i64 %a, i64 %b) {
31 ; CHECK-LABEL: f3:
32 ; CHECK-NOT: {{%r[23]}}
33 ; CHECK: lr %r2, %r3
34 ; CHECK: br %r14
35   %low = and i64 %b, 4294967295
36   %high = and i64 %a, -4294967296
37   %res = or i64 %high, %low
38   ret i64 %res
39 }
40
41 ; ... and again with the operands reversed.
42 define i64 @f4(i64 %a, i64 %b) {
43 ; CHECK-LABEL: f4:
44 ; CHECK-NOT: {{%r[23]}}
45 ; CHECK: lr %r2, %r3
46 ; CHECK: br %r14
47   %low = and i64 %b, 4294967295
48   %high = and i64 %a, -4294967296
49   %res = or i64 %low, %high
50   ret i64 %res
51 }
52
53 ; Unary operations can be done directly into the low half.
54 define i64 @f5(i64 %a, i32 %b) {
55 ; CHECK-LABEL: f5:
56 ; CHECK-NOT: {{%r[23]}}
57 ; CHECK: lcr %r2, %r3
58 ; CHECK: br %r14
59   %neg = sub i32 0, %b
60   %low = zext i32 %neg to i64
61   %high = and i64 %a, -4294967296
62   %res = or i64 %high, %low
63   ret i64 %res
64 }
65
66 ; ...likewise three-operand binary operations like RLL.
67 define i64 @f6(i64 %a, i32 %b) {
68 ; CHECK-LABEL: f6:
69 ; CHECK-NOT: {{%r[23]}}
70 ; CHECK: rll %r2, %r3, 1
71 ; CHECK: br %r14
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
78   ret i64 %res
79 }
80
81 ; Loads can be done directly into the low half.  The range of L is checked
82 ; in the move tests.
83 define i64 @f7(i64 %a, i32 *%src) {
84 ; CHECK-LABEL: f7:
85 ; CHECK-NOT: {{%r[23]}}
86 ; CHECK: l %r2, 0(%r3)
87 ; CHECK: br %r14
88   %b = load i32 *%src
89   %low = zext i32 %b to i64
90   %high = and i64 %a, -4294967296
91   %res = or i64 %high, %low
92   ret i64 %res
93 }
94
95 ; ...likewise extending loads.
96 define i64 @f8(i64 %a, i8 *%src) {
97 ; CHECK-LABEL: f8:
98 ; CHECK-NOT: {{%r[23]}}
99 ; CHECK: lb %r2, 0(%r3)
100 ; CHECK: br %r14
101   %byte = load 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
106   ret i64 %res
107 }
108
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
111 ; both clear.
112 define i64 @f9(i64 %a, i32 %b) {
113 ; CHECK-LABEL: f9:
114 ; CHECK: sllg %r2, %r2, 32
115 ; CHECK: lr %r2, %r3
116 ; CHECK: br %r14
117   %shift = shl i64 %a, 32
118   %low = zext i32 %b to i64
119   %or = or i64 %shift, %low
120   ret i64 %or
121 }
122
123 ; ...and again with the operands reversed.
124 define i64 @f10(i64 %a, i32 %b) {
125 ; CHECK-LABEL: f10:
126 ; CHECK: sllg %r2, %r2, 32
127 ; CHECK: lr %r2, %r3
128 ; CHECK: br %r14
129   %shift = shl i64 %a, 32
130   %low = zext i32 %b to i64
131   %or = or i64 %low, %shift
132   ret i64 %or
133 }
134
135 ; Like f9, but with "in register" zero extension.
136 define i64 @f11(i64 %a, i64 %b) {
137 ; CHECK-LABEL: f11:
138 ; CHECK: lr %r2, %r3
139 ; CHECK: br %r14
140   %shift = shl i64 %a, 32
141   %low = and i64 %b, 4294967295
142   %or = or i64 %shift, %low
143   ret i64 %or
144 }
145
146 ; ...and again with the operands reversed.
147 define i64 @f12(i64 %a, i64 %b) {
148 ; CHECK-LABEL: f12:
149 ; CHECK: lr %r2, %r3
150 ; CHECK: br %r14
151   %shift = shl i64 %a, 32
152   %low = and i64 %b, 4294967295
153   %or = or i64 %low, %shift
154   ret i64 %or
155 }
156
157 ; Like f9, but for larger shifts than 32.
158 define i64 @f13(i64 %a, i32 %b) {
159 ; CHECK-LABEL: f13:
160 ; CHECK: sllg %r2, %r2, 60
161 ; CHECK: lr %r2, %r3
162 ; CHECK: br %r14
163   %shift = shl i64 %a, 60
164   %low = zext i32 %b to i64
165   %or = or i64 %shift, %low
166   ret i64 %or
167 }
168
169 ; We previously wrongly removed the upper AND as dead.
170 define i64 @f14(i64 %a, i64 %b) {
171 ; CHECK-LABEL: f14:
172 ; CHECK: risbg {{%r[0-5]}}, %r2, 6, 134, 0
173 ; CHECK: br %r14
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
179   ret i64 %ext
180 }