1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,NOBMI -enable-var-scope 3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs -mattr=+bmi | FileCheck %s -check-prefixes=CHECK,BMI -enable-var-scope 4 5 define i32 @select_and1(i32 %x, i32 %y) { 6 ; CHECK-LABEL: select_and1: 7 ; CHECK: # %bb.0: 8 ; CHECK-NEXT: xorl %eax, %eax 9 ; CHECK-NEXT: cmpl $11, %edi 10 ; CHECK-NEXT: cmovgel %esi, %eax 11 ; CHECK-NEXT: retq 12 %c = icmp slt i32 %x, 11 13 %s = select i1 %c, i32 0, i32 -1 14 %a = and i32 %y, %s 15 ret i32 %a 16 } 17 18 define i32 @select_and2(i32 %x, i32 %y) { 19 ; CHECK-LABEL: select_and2: 20 ; CHECK: # %bb.0: 21 ; CHECK-NEXT: xorl %eax, %eax 22 ; CHECK-NEXT: cmpl $11, %edi 23 ; CHECK-NEXT: cmovgel %esi, %eax 24 ; CHECK-NEXT: retq 25 %c = icmp slt i32 %x, 11 26 %s = select i1 %c, i32 0, i32 -1 27 %a = and i32 %s, %y 28 ret i32 %a 29 } 30 31 define i32 @select_and3(i32 %x, i32 %y) { 32 ; CHECK-LABEL: select_and3: 33 ; CHECK: # %bb.0: 34 ; CHECK-NEXT: xorl %eax, %eax 35 ; CHECK-NEXT: cmpl $11, %edi 36 ; CHECK-NEXT: cmovll %esi, %eax 37 ; CHECK-NEXT: retq 38 %c = icmp slt i32 %x, 11 39 %s = select i1 %c, i32 -1, i32 0 40 %a = and i32 %y, %s 41 ret i32 %a 42 } 43 44 define <4 x i32> @select_and_v4(i32 %x, <4 x i32> %y) { 45 ; CHECK-LABEL: select_and_v4: 46 ; CHECK: # %bb.0: 47 ; CHECK-NEXT: cmpl $11, %edi 48 ; CHECK-NEXT: xorps %xmm1, %xmm1 49 ; CHECK-NEXT: jl .LBB3_2 50 ; CHECK-NEXT: # %bb.1: 51 ; CHECK-NEXT: movaps %xmm0, %xmm1 52 ; CHECK-NEXT: .LBB3_2: 53 ; CHECK-NEXT: movaps %xmm1, %xmm0 54 ; CHECK-NEXT: retq 55 %c = icmp slt i32 %x, 11 56 %s = select i1 %c, <4 x i32> zeroinitializer, <4 x i32><i32 -1, i32 -1, i32 -1, i32 -1> 57 %a = and <4 x i32> %s, %y 58 ret <4 x i32> %a 59 } 60 61 define i32 @select_or1(i32 %x, i32 %y) { 62 ; CHECK-LABEL: select_or1: 63 ; CHECK: # %bb.0: 64 ; CHECK-NEXT: cmpl $11, %edi 65 ; CHECK-NEXT: movl $-1, %eax 66 ; CHECK-NEXT: cmovll %esi, %eax 67 ; CHECK-NEXT: retq 68 %c = icmp slt i32 %x, 11 69 %s = select i1 %c, i32 0, i32 -1 70 %a = or i32 %y, %s 71 ret i32 %a 72 } 73 74 define i32 @select_or2(i32 %x, i32 %y) { 75 ; CHECK-LABEL: select_or2: 76 ; CHECK: # %bb.0: 77 ; CHECK-NEXT: cmpl $11, %edi 78 ; CHECK-NEXT: movl $-1, %eax 79 ; CHECK-NEXT: cmovll %esi, %eax 80 ; CHECK-NEXT: retq 81 %c = icmp slt i32 %x, 11 82 %s = select i1 %c, i32 0, i32 -1 83 %a = or i32 %s, %y 84 ret i32 %a 85 } 86 87 define i32 @select_or3(i32 %x, i32 %y) { 88 ; CHECK-LABEL: select_or3: 89 ; CHECK: # %bb.0: 90 ; CHECK-NEXT: cmpl $11, %edi 91 ; CHECK-NEXT: movl $-1, %eax 92 ; CHECK-NEXT: cmovgel %esi, %eax 93 ; CHECK-NEXT: retq 94 %c = icmp slt i32 %x, 11 95 %s = select i1 %c, i32 -1, i32 0 96 %a = or i32 %y, %s 97 ret i32 %a 98 } 99 100 define <4 x i32> @select_or_v4(i32 %x, <4 x i32> %y) { 101 ; CHECK-LABEL: select_or_v4: 102 ; CHECK: # %bb.0: 103 ; CHECK-NEXT: cmpl $11, %edi 104 ; CHECK-NEXT: jl .LBB7_2 105 ; CHECK-NEXT: # %bb.1: 106 ; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 107 ; CHECK-NEXT: .LBB7_2: 108 ; CHECK-NEXT: retq 109 %c = icmp slt i32 %x, 11 110 %s = select i1 %c, <4 x i32> zeroinitializer, <4 x i32><i32 -1, i32 -1, i32 -1, i32 -1> 111 %a = or <4 x i32> %s, %y 112 ret <4 x i32> %a 113 } 114 115 define i32 @sel_constants_sub_constant_sel_constants(i1 %cond) { 116 ; CHECK-LABEL: sel_constants_sub_constant_sel_constants: 117 ; CHECK: # %bb.0: 118 ; CHECK-NEXT: testb $1, %dil 119 ; CHECK-NEXT: movl $9, %ecx 120 ; CHECK-NEXT: movl $2, %eax 121 ; CHECK-NEXT: cmovnel %ecx, %eax 122 ; CHECK-NEXT: retq 123 %sel = select i1 %cond, i32 -4, i32 3 124 %bo = sub i32 5, %sel 125 ret i32 %bo 126 } 127 128 define i32 @sdiv_constant_sel_constants(i1 %cond) { 129 ; CHECK-LABEL: sdiv_constant_sel_constants: 130 ; CHECK: # %bb.0: 131 ; CHECK-NEXT: notb %dil 132 ; CHECK-NEXT: movzbl %dil, %eax 133 ; CHECK-NEXT: andl $1, %eax 134 ; CHECK-NEXT: leal (%rax,%rax,4), %eax 135 ; CHECK-NEXT: retq 136 %sel = select i1 %cond, i32 121, i32 23 137 %bo = sdiv i32 120, %sel 138 ret i32 %bo 139 } 140 141 define i32 @udiv_constant_sel_constants(i1 %cond) { 142 ; CHECK-LABEL: udiv_constant_sel_constants: 143 ; CHECK: # %bb.0: 144 ; CHECK-NEXT: notb %dil 145 ; CHECK-NEXT: movzbl %dil, %eax 146 ; CHECK-NEXT: andl $1, %eax 147 ; CHECK-NEXT: leal (%rax,%rax,4), %eax 148 ; CHECK-NEXT: retq 149 %sel = select i1 %cond, i32 -4, i32 23 150 %bo = udiv i32 120, %sel 151 ret i32 %bo 152 } 153 154 define i32 @srem_constant_sel_constants(i1 %cond) { 155 ; CHECK-LABEL: srem_constant_sel_constants: 156 ; CHECK: # %bb.0: 157 ; CHECK-NEXT: testb $1, %dil 158 ; CHECK-NEXT: movl $120, %ecx 159 ; CHECK-NEXT: movl $5, %eax 160 ; CHECK-NEXT: cmovnel %ecx, %eax 161 ; CHECK-NEXT: retq 162 %sel = select i1 %cond, i32 121, i32 23 163 %bo = srem i32 120, %sel 164 ret i32 %bo 165 } 166 167 define i32 @urem_constant_sel_constants(i1 %cond) { 168 ; CHECK-LABEL: urem_constant_sel_constants: 169 ; CHECK: # %bb.0: 170 ; CHECK-NEXT: testb $1, %dil 171 ; CHECK-NEXT: movl $120, %ecx 172 ; CHECK-NEXT: movl $5, %eax 173 ; CHECK-NEXT: cmovnel %ecx, %eax 174 ; CHECK-NEXT: retq 175 %sel = select i1 %cond, i32 -4, i32 23 176 %bo = urem i32 120, %sel 177 ret i32 %bo 178 } 179 180 define i32 @sel_constants_shl_constant(i1 %cond) { 181 ; CHECK-LABEL: sel_constants_shl_constant: 182 ; CHECK: # %bb.0: 183 ; CHECK-NEXT: notb %dil 184 ; CHECK-NEXT: movzbl %dil, %eax 185 ; CHECK-NEXT: andl $1, %eax 186 ; CHECK-NEXT: orl $2, %eax 187 ; CHECK-NEXT: shll $8, %eax 188 ; CHECK-NEXT: retq 189 %sel = select i1 %cond, i32 2, i32 3 190 %bo = shl i32 %sel, 8 191 ret i32 %bo 192 } 193 194 define i32 @shl_constant_sel_constants(i1 %cond) { 195 ; CHECK-LABEL: shl_constant_sel_constants: 196 ; CHECK: # %bb.0: 197 ; CHECK-NEXT: andb $1, %dil 198 ; CHECK-NEXT: xorb $3, %dil 199 ; CHECK-NEXT: movl $1, %eax 200 ; CHECK-NEXT: movl %edi, %ecx 201 ; CHECK-NEXT: shll %cl, %eax 202 ; CHECK-NEXT: retq 203 %sel = select i1 %cond, i32 2, i32 3 204 %bo = shl i32 1, %sel 205 ret i32 %bo 206 } 207 208 define i32 @lshr_constant_sel_constants(i1 %cond) { 209 ; CHECK-LABEL: lshr_constant_sel_constants: 210 ; CHECK: # %bb.0: 211 ; CHECK-NEXT: andb $1, %dil 212 ; CHECK-NEXT: xorb $3, %dil 213 ; CHECK-NEXT: movl $64, %eax 214 ; CHECK-NEXT: movl %edi, %ecx 215 ; CHECK-NEXT: shrl %cl, %eax 216 ; CHECK-NEXT: retq 217 %sel = select i1 %cond, i32 2, i32 3 218 %bo = lshr i32 64, %sel 219 ret i32 %bo 220 } 221 222 define i32 @ashr_constant_sel_constants(i1 %cond) { 223 ; CHECK-LABEL: ashr_constant_sel_constants: 224 ; CHECK: # %bb.0: 225 ; CHECK-NEXT: andb $1, %dil 226 ; CHECK-NEXT: xorb $3, %dil 227 ; CHECK-NEXT: movl $128, %eax 228 ; CHECK-NEXT: movl %edi, %ecx 229 ; CHECK-NEXT: shrl %cl, %eax 230 ; CHECK-NEXT: retq 231 %sel = select i1 %cond, i32 2, i32 3 232 %bo = ashr i32 128, %sel 233 ret i32 %bo 234 } 235 236 define double @fsub_constant_sel_constants(i1 %cond) { 237 ; CHECK-LABEL: fsub_constant_sel_constants: 238 ; CHECK: # %bb.0: 239 ; CHECK-NEXT: testb $1, %dil 240 ; CHECK-NEXT: jne .LBB17_1 241 ; CHECK-NEXT: # %bb.2: 242 ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 243 ; CHECK-NEXT: retq 244 ; CHECK-NEXT: .LBB17_1: 245 ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 246 ; CHECK-NEXT: retq 247 %sel = select i1 %cond, double -4.0, double 23.3 248 %bo = fsub double 5.1, %sel 249 ret double %bo 250 } 251 252 define double @fdiv_constant_sel_constants(i1 %cond) { 253 ; CHECK-LABEL: fdiv_constant_sel_constants: 254 ; CHECK: # %bb.0: 255 ; CHECK-NEXT: testb $1, %dil 256 ; CHECK-NEXT: jne .LBB18_1 257 ; CHECK-NEXT: # %bb.2: 258 ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 259 ; CHECK-NEXT: retq 260 ; CHECK-NEXT: .LBB18_1: 261 ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 262 ; CHECK-NEXT: retq 263 %sel = select i1 %cond, double -4.0, double 23.3 264 %bo = fdiv double 5.1, %sel 265 ret double %bo 266 } 267 268 define double @frem_constant_sel_constants(i1 %cond) { 269 ; CHECK-LABEL: frem_constant_sel_constants: 270 ; CHECK: # %bb.0: 271 ; CHECK-NEXT: testb $1, %dil 272 ; CHECK-NEXT: jne .LBB19_1 273 ; CHECK-NEXT: # %bb.2: 274 ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 275 ; CHECK-NEXT: retq 276 ; CHECK-NEXT: .LBB19_1: 277 ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero 278 ; CHECK-NEXT: retq 279 %sel = select i1 %cond, double -4.0, double 23.3 280 %bo = frem double 5.1, %sel 281 ret double %bo 282 } 283 284 declare i64 @llvm.cttz.i64(i64, i1) 285 define i64 @cttz_64_eq_select(i64 %v) nounwind { 286 ; NOBMI-LABEL: cttz_64_eq_select: 287 ; NOBMI: # %bb.0: 288 ; NOBMI-NEXT: bsfq %rdi, %rcx 289 ; NOBMI-NEXT: movq $-1, %rax 290 ; NOBMI-NEXT: cmovneq %rcx, %rax 291 ; NOBMI-NEXT: addq $6, %rax 292 ; NOBMI-NEXT: retq 293 ; 294 ; BMI-LABEL: cttz_64_eq_select: 295 ; BMI: # %bb.0: 296 ; BMI-NEXT: tzcntq %rdi, %rcx 297 ; BMI-NEXT: movq $-1, %rax 298 ; BMI-NEXT: cmovaeq %rcx, %rax 299 ; BMI-NEXT: addq $6, %rax 300 ; BMI-NEXT: retq 301 302 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true) 303 %tobool = icmp eq i64 %v, 0 304 %.op = add nuw nsw i64 %cnt, 6 305 %add = select i1 %tobool, i64 5, i64 %.op 306 ret i64 %add 307 } 308 309 define i64 @cttz_64_ne_select(i64 %v) nounwind { 310 ; NOBMI-LABEL: cttz_64_ne_select: 311 ; NOBMI: # %bb.0: 312 ; NOBMI-NEXT: bsfq %rdi, %rcx 313 ; NOBMI-NEXT: movq $-1, %rax 314 ; NOBMI-NEXT: cmovneq %rcx, %rax 315 ; NOBMI-NEXT: addq $6, %rax 316 ; NOBMI-NEXT: retq 317 ; 318 ; BMI-LABEL: cttz_64_ne_select: 319 ; BMI: # %bb.0: 320 ; BMI-NEXT: tzcntq %rdi, %rcx 321 ; BMI-NEXT: movq $-1, %rax 322 ; BMI-NEXT: cmovaeq %rcx, %rax 323 ; BMI-NEXT: addq $6, %rax 324 ; BMI-NEXT: retq 325 326 %cnt = tail call i64 @llvm.cttz.i64(i64 %v, i1 true) 327 %tobool = icmp ne i64 %v, 0 328 %.op = add nuw nsw i64 %cnt, 6 329 %add = select i1 %tobool, i64 %.op, i64 5 330 ret i64 %add 331 } 332 333 declare i32 @llvm.cttz.i32(i32, i1) 334 define i32 @cttz_32_eq_select(i32 %v) nounwind { 335 ; NOBMI-LABEL: cttz_32_eq_select: 336 ; NOBMI: # %bb.0: 337 ; NOBMI-NEXT: bsfl %edi, %ecx 338 ; NOBMI-NEXT: movl $-1, %eax 339 ; NOBMI-NEXT: cmovnel %ecx, %eax 340 ; NOBMI-NEXT: addl $6, %eax 341 ; NOBMI-NEXT: retq 342 ; 343 ; BMI-LABEL: cttz_32_eq_select: 344 ; BMI: # %bb.0: 345 ; BMI-NEXT: tzcntl %edi, %ecx 346 ; BMI-NEXT: movl $-1, %eax 347 ; BMI-NEXT: cmovael %ecx, %eax 348 ; BMI-NEXT: addl $6, %eax 349 ; BMI-NEXT: retq 350 351 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true) 352 %tobool = icmp eq i32 %v, 0 353 %.op = add nuw nsw i32 %cnt, 6 354 %add = select i1 %tobool, i32 5, i32 %.op 355 ret i32 %add 356 } 357 358 define i32 @cttz_32_ne_select(i32 %v) nounwind { 359 ; NOBMI-LABEL: cttz_32_ne_select: 360 ; NOBMI: # %bb.0: 361 ; NOBMI-NEXT: bsfl %edi, %ecx 362 ; NOBMI-NEXT: movl $-1, %eax 363 ; NOBMI-NEXT: cmovnel %ecx, %eax 364 ; NOBMI-NEXT: addl $6, %eax 365 ; NOBMI-NEXT: retq 366 ; 367 ; BMI-LABEL: cttz_32_ne_select: 368 ; BMI: # %bb.0: 369 ; BMI-NEXT: tzcntl %edi, %ecx 370 ; BMI-NEXT: movl $-1, %eax 371 ; BMI-NEXT: cmovael %ecx, %eax 372 ; BMI-NEXT: addl $6, %eax 373 ; BMI-NEXT: retq 374 375 %cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true) 376 %tobool = icmp ne i32 %v, 0 377 %.op = add nuw nsw i32 %cnt, 6 378 %add = select i1 %tobool, i32 %.op, i32 5 379 ret i32 %add 380 } 381