1; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+bmi,+bmi2,+popcnt | FileCheck %s
2declare void @foo(i32)
3declare void @foo64(i64)
4
5; CHECK-LABEL: neg:
6; CHECK: negl %edi
7; CHECK-NEXT: je
8; CHECK: jmp foo
9; CHECK: ret
10define void @neg(i32 %x) nounwind {
11  %sub = sub i32 0, %x
12  %cmp = icmp eq i32 %sub, 0
13  br i1 %cmp, label %return, label %bb
14
15bb:
16  tail call void @foo(i32 %sub)
17  br label %return
18
19return:
20  ret void
21}
22
23; CHECK-LABEL: sar:
24; CHECK: sarl %edi
25; CHECK-NEXT: je
26; CHECK: jmp foo
27; CHECK: ret
28define void @sar(i32 %x) nounwind {
29  %ashr = ashr i32 %x, 1
30  %cmp = icmp eq i32 %ashr, 0
31  br i1 %cmp, label %return, label %bb
32
33bb:
34  tail call void @foo(i32 %ashr)
35  br label %return
36
37return:
38  ret void
39}
40
41; CHECK-LABEL: shr:
42; CHECK: shrl %edi
43; CHECK-NEXT: je
44; CHECK: jmp foo
45; CHECK: ret
46define void @shr(i32 %x) nounwind {
47  %ashr = lshr i32 %x, 1
48  %cmp = icmp eq i32 %ashr, 0
49  br i1 %cmp, label %return, label %bb
50
51bb:
52  tail call void @foo(i32 %ashr)
53  br label %return
54
55return:
56  ret void
57}
58
59; CHECK-LABEL: shri:
60; CHECK: shrl $3, %edi
61; CHECK-NEXT: je
62; CHECK: jmp foo
63; CHECK: ret
64define void @shri(i32 %x) nounwind {
65  %ashr = lshr i32 %x, 3
66  %cmp = icmp eq i32 %ashr, 0
67  br i1 %cmp, label %return, label %bb
68
69bb:
70  tail call void @foo(i32 %ashr)
71  br label %return
72
73return:
74  ret void
75}
76
77; CHECK-LABEL: shl:
78; CHECK: addl %edi, %edi
79; CHECK-NEXT: je
80; CHECK: jmp foo
81; CHECK: ret
82define void @shl(i32 %x) nounwind {
83  %shl = shl i32 %x, 1
84  %cmp = icmp eq i32 %shl, 0
85  br i1 %cmp, label %return, label %bb
86
87bb:
88  tail call void @foo(i32 %shl)
89  br label %return
90
91return:
92  ret void
93}
94
95; CHECK-LABEL: shli:
96; CHECK: shll $4, %edi
97; CHECK-NEXT: je
98; CHECK: jmp foo
99; CHECK: ret
100define void @shli(i32 %x) nounwind {
101  %shl = shl i32 %x, 4
102  %cmp = icmp eq i32 %shl, 0
103  br i1 %cmp, label %return, label %bb
104
105bb:
106  tail call void @foo(i32 %shl)
107  br label %return
108
109return:
110  ret void
111}
112
113; CHECK-LABEL: adc:
114; CHECK: movabsq $-9223372036854775808, %rax
115; CHECK-NEXT: addq  %rdi, %rax
116; CHECK-NEXT: adcq  $0, %rsi
117; CHECK-NEXT: sete  %al
118; CHECK: ret
119define zeroext i1 @adc(i128 %x) nounwind {
120  %add = add i128 %x, 9223372036854775808
121  %cmp = icmp ult i128 %add, 18446744073709551616
122  ret i1 %cmp
123}
124
125; CHECK-LABEL: sbb:
126; CHECK: cmpq  %rdx, %rdi
127; CHECK-NEXT: sbbq  %rcx, %rsi
128; CHECK-NEXT: setns %al
129; CHECK: ret
130define zeroext i1 @sbb(i128 %x, i128 %y) nounwind {
131  %sub = sub i128 %x, %y
132  %cmp = icmp sge i128 %sub, 0
133  ret i1 %cmp
134}
135
136; CHECK-LABEL: andn:
137; CHECK: andnl   %esi, %edi, %edi
138; CHECK-NEXT: je
139; CHECK: jmp foo
140; CHECK: ret
141define void @andn(i32 %x, i32 %y) nounwind {
142  %not = xor i32 %x, -1
143  %andn = and i32 %y, %not
144  %cmp = icmp eq i32 %andn, 0
145  br i1 %cmp, label %return, label %bb
146
147bb:
148  tail call void @foo(i32 %andn)
149  br label %return
150
151return:
152  ret void
153}
154
155; CHECK-LABEL: bextr:
156; CHECK: bextrl   %esi, %edi, %edi
157; CHECK-NEXT: je
158; CHECK: jmp foo
159; CHECK: ret
160declare i32 @llvm.x86.bmi.bextr.32(i32, i32) nounwind readnone
161define void @bextr(i32 %x, i32 %y) nounwind {
162  %bextr = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x, i32 %y)
163  %cmp = icmp eq i32 %bextr, 0
164  br i1 %cmp, label %return, label %bb
165
166bb:
167  tail call void @foo(i32 %bextr)
168  br label %return
169
170return:
171  ret void
172}
173
174; CHECK-LABEL: popcnt:
175; CHECK: popcntl
176; CHECK-NEXT: je
177; CHECK: jmp foo
178; CHECK: ret
179declare i32 @llvm.ctpop.i32(i32) nounwind readnone
180define void @popcnt(i32 %x) nounwind {
181  %popcnt = tail call i32 @llvm.ctpop.i32(i32 %x)
182  %cmp = icmp eq i32 %popcnt, 0
183  br i1 %cmp, label %return, label %bb
184;
185bb:
186  tail call void @foo(i32 %popcnt)
187  br label %return
188;
189return:
190  ret void
191}
192