1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi < %s | FileCheck %s --check-prefix=CHECK-NOBMI 3 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi < %s | FileCheck %s --check-prefix=CHECK-BMI 4 ; https://bugs.llvm.org/show_bug.cgi?id=37104 5 6 define i8 @out8(i8 %x, i8 %y, i8 %mask) { 7 ; CHECK-NOBMI-LABEL: out8: 8 ; CHECK-NOBMI: # %bb.0: 9 ; CHECK-NOBMI-NEXT: andl %edx, %edi 10 ; CHECK-NOBMI-NEXT: notb %dl 11 ; CHECK-NOBMI-NEXT: andb %sil, %dl 12 ; CHECK-NOBMI-NEXT: orb %dil, %dl 13 ; CHECK-NOBMI-NEXT: movl %edx, %eax 14 ; CHECK-NOBMI-NEXT: retq 15 ; 16 ; CHECK-BMI-LABEL: out8: 17 ; CHECK-BMI: # %bb.0: 18 ; CHECK-BMI-NEXT: andl %edx, %edi 19 ; CHECK-BMI-NEXT: notb %dl 20 ; CHECK-BMI-NEXT: andb %sil, %dl 21 ; CHECK-BMI-NEXT: orb %dil, %dl 22 ; CHECK-BMI-NEXT: movl %edx, %eax 23 ; CHECK-BMI-NEXT: retq 24 %mx = and i8 %x, %mask 25 %notmask = xor i8 %mask, -1 26 %my = and i8 %y, %notmask 27 %r = or i8 %mx, %my 28 ret i8 %r 29 } 30 31 define i16 @out16(i16 %x, i16 %y, i16 %mask) { 32 ; CHECK-NOBMI-LABEL: out16: 33 ; CHECK-NOBMI: # %bb.0: 34 ; CHECK-NOBMI-NEXT: andl %edx, %edi 35 ; CHECK-NOBMI-NEXT: notl %edx 36 ; CHECK-NOBMI-NEXT: andl %esi, %edx 37 ; CHECK-NOBMI-NEXT: orl %edi, %edx 38 ; CHECK-NOBMI-NEXT: movl %edx, %eax 39 ; CHECK-NOBMI-NEXT: retq 40 ; 41 ; CHECK-BMI-LABEL: out16: 42 ; CHECK-BMI: # %bb.0: 43 ; CHECK-BMI-NEXT: andl %edx, %edi 44 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 45 ; CHECK-BMI-NEXT: orl %edi, %eax 46 ; CHECK-BMI-NEXT: # kill: def $ax killed $ax killed $eax 47 ; CHECK-BMI-NEXT: retq 48 %mx = and i16 %x, %mask 49 %notmask = xor i16 %mask, -1 50 %my = and i16 %y, %notmask 51 %r = or i16 %mx, %my 52 ret i16 %r 53 } 54 55 define i32 @out32(i32 %x, i32 %y, i32 %mask) { 56 ; CHECK-NOBMI-LABEL: out32: 57 ; CHECK-NOBMI: # %bb.0: 58 ; CHECK-NOBMI-NEXT: andl %edx, %edi 59 ; CHECK-NOBMI-NEXT: notl %edx 60 ; CHECK-NOBMI-NEXT: andl %esi, %edx 61 ; CHECK-NOBMI-NEXT: orl %edi, %edx 62 ; CHECK-NOBMI-NEXT: movl %edx, %eax 63 ; CHECK-NOBMI-NEXT: retq 64 ; 65 ; CHECK-BMI-LABEL: out32: 66 ; CHECK-BMI: # %bb.0: 67 ; CHECK-BMI-NEXT: andl %edx, %edi 68 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 69 ; CHECK-BMI-NEXT: orl %edi, %eax 70 ; CHECK-BMI-NEXT: retq 71 %mx = and i32 %x, %mask 72 %notmask = xor i32 %mask, -1 73 %my = and i32 %y, %notmask 74 %r = or i32 %mx, %my 75 ret i32 %r 76 } 77 78 define i64 @out64(i64 %x, i64 %y, i64 %mask) { 79 ; CHECK-NOBMI-LABEL: out64: 80 ; CHECK-NOBMI: # %bb.0: 81 ; CHECK-NOBMI-NEXT: andq %rdx, %rdi 82 ; CHECK-NOBMI-NEXT: notq %rdx 83 ; CHECK-NOBMI-NEXT: andq %rsi, %rdx 84 ; CHECK-NOBMI-NEXT: orq %rdi, %rdx 85 ; CHECK-NOBMI-NEXT: movq %rdx, %rax 86 ; CHECK-NOBMI-NEXT: retq 87 ; 88 ; CHECK-BMI-LABEL: out64: 89 ; CHECK-BMI: # %bb.0: 90 ; CHECK-BMI-NEXT: andq %rdx, %rdi 91 ; CHECK-BMI-NEXT: andnq %rsi, %rdx, %rax 92 ; CHECK-BMI-NEXT: orq %rdi, %rax 93 ; CHECK-BMI-NEXT: retq 94 %mx = and i64 %x, %mask 95 %notmask = xor i64 %mask, -1 96 %my = and i64 %y, %notmask 97 %r = or i64 %mx, %my 98 ret i64 %r 99 } 100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 101 ; Should be the same as the previous one. 102 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 103 104 define i8 @in8(i8 %x, i8 %y, i8 %mask) { 105 ; CHECK-NOBMI-LABEL: in8: 106 ; CHECK-NOBMI: # %bb.0: 107 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 108 ; CHECK-NOBMI-NEXT: andl %edx, %edi 109 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 110 ; CHECK-NOBMI-NEXT: movl %edi, %eax 111 ; CHECK-NOBMI-NEXT: retq 112 ; 113 ; CHECK-BMI-LABEL: in8: 114 ; CHECK-BMI: # %bb.0: 115 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 116 ; CHECK-BMI-NEXT: andl %edx, %edi 117 ; CHECK-BMI-NEXT: orl %edi, %eax 118 ; CHECK-BMI-NEXT: # kill: def $al killed $al killed $eax 119 ; CHECK-BMI-NEXT: retq 120 %n0 = xor i8 %x, %y 121 %n1 = and i8 %n0, %mask 122 %r = xor i8 %n1, %y 123 ret i8 %r 124 } 125 126 define i16 @in16(i16 %x, i16 %y, i16 %mask) { 127 ; CHECK-NOBMI-LABEL: in16: 128 ; CHECK-NOBMI: # %bb.0: 129 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 130 ; CHECK-NOBMI-NEXT: andl %edx, %edi 131 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 132 ; CHECK-NOBMI-NEXT: movl %edi, %eax 133 ; CHECK-NOBMI-NEXT: retq 134 ; 135 ; CHECK-BMI-LABEL: in16: 136 ; CHECK-BMI: # %bb.0: 137 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 138 ; CHECK-BMI-NEXT: andl %edx, %edi 139 ; CHECK-BMI-NEXT: orl %edi, %eax 140 ; CHECK-BMI-NEXT: # kill: def $ax killed $ax killed $eax 141 ; CHECK-BMI-NEXT: retq 142 %n0 = xor i16 %x, %y 143 %n1 = and i16 %n0, %mask 144 %r = xor i16 %n1, %y 145 ret i16 %r 146 } 147 148 define i32 @in32(i32 %x, i32 %y, i32 %mask) { 149 ; CHECK-NOBMI-LABEL: in32: 150 ; CHECK-NOBMI: # %bb.0: 151 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 152 ; CHECK-NOBMI-NEXT: andl %edx, %edi 153 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 154 ; CHECK-NOBMI-NEXT: movl %edi, %eax 155 ; CHECK-NOBMI-NEXT: retq 156 ; 157 ; CHECK-BMI-LABEL: in32: 158 ; CHECK-BMI: # %bb.0: 159 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 160 ; CHECK-BMI-NEXT: andl %edx, %edi 161 ; CHECK-BMI-NEXT: orl %edi, %eax 162 ; CHECK-BMI-NEXT: retq 163 %n0 = xor i32 %x, %y 164 %n1 = and i32 %n0, %mask 165 %r = xor i32 %n1, %y 166 ret i32 %r 167 } 168 169 define i64 @in64(i64 %x, i64 %y, i64 %mask) { 170 ; CHECK-NOBMI-LABEL: in64: 171 ; CHECK-NOBMI: # %bb.0: 172 ; CHECK-NOBMI-NEXT: xorq %rsi, %rdi 173 ; CHECK-NOBMI-NEXT: andq %rdx, %rdi 174 ; CHECK-NOBMI-NEXT: xorq %rsi, %rdi 175 ; CHECK-NOBMI-NEXT: movq %rdi, %rax 176 ; CHECK-NOBMI-NEXT: retq 177 ; 178 ; CHECK-BMI-LABEL: in64: 179 ; CHECK-BMI: # %bb.0: 180 ; CHECK-BMI-NEXT: andnq %rsi, %rdx, %rax 181 ; CHECK-BMI-NEXT: andq %rdx, %rdi 182 ; CHECK-BMI-NEXT: orq %rdi, %rax 183 ; CHECK-BMI-NEXT: retq 184 %n0 = xor i64 %x, %y 185 %n1 = and i64 %n0, %mask 186 %r = xor i64 %n1, %y 187 ret i64 %r 188 } 189 ; ============================================================================ ; 190 ; Commutativity tests. 191 ; ============================================================================ ; 192 define i32 @in_commutativity_0_0_1(i32 %x, i32 %y, i32 %mask) { 193 ; CHECK-NOBMI-LABEL: in_commutativity_0_0_1: 194 ; CHECK-NOBMI: # %bb.0: 195 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 196 ; CHECK-NOBMI-NEXT: andl %edx, %edi 197 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 198 ; CHECK-NOBMI-NEXT: movl %edi, %eax 199 ; CHECK-NOBMI-NEXT: retq 200 ; 201 ; CHECK-BMI-LABEL: in_commutativity_0_0_1: 202 ; CHECK-BMI: # %bb.0: 203 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 204 ; CHECK-BMI-NEXT: andl %edx, %edi 205 ; CHECK-BMI-NEXT: orl %edi, %eax 206 ; CHECK-BMI-NEXT: retq 207 %n0 = xor i32 %x, %y 208 %n1 = and i32 %mask, %n0 ; swapped 209 %r = xor i32 %n1, %y 210 ret i32 %r 211 } 212 define i32 @in_commutativity_0_1_0(i32 %x, i32 %y, i32 %mask) { 213 ; CHECK-NOBMI-LABEL: in_commutativity_0_1_0: 214 ; CHECK-NOBMI: # %bb.0: 215 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 216 ; CHECK-NOBMI-NEXT: andl %edx, %edi 217 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 218 ; CHECK-NOBMI-NEXT: movl %edi, %eax 219 ; CHECK-NOBMI-NEXT: retq 220 ; 221 ; CHECK-BMI-LABEL: in_commutativity_0_1_0: 222 ; CHECK-BMI: # %bb.0: 223 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 224 ; CHECK-BMI-NEXT: andl %edx, %edi 225 ; CHECK-BMI-NEXT: orl %edi, %eax 226 ; CHECK-BMI-NEXT: retq 227 %n0 = xor i32 %x, %y 228 %n1 = and i32 %n0, %mask 229 %r = xor i32 %y, %n1 ; swapped 230 ret i32 %r 231 } 232 define i32 @in_commutativity_0_1_1(i32 %x, i32 %y, i32 %mask) { 233 ; CHECK-NOBMI-LABEL: in_commutativity_0_1_1: 234 ; CHECK-NOBMI: # %bb.0: 235 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 236 ; CHECK-NOBMI-NEXT: andl %edx, %edi 237 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 238 ; CHECK-NOBMI-NEXT: movl %edi, %eax 239 ; CHECK-NOBMI-NEXT: retq 240 ; 241 ; CHECK-BMI-LABEL: in_commutativity_0_1_1: 242 ; CHECK-BMI: # %bb.0: 243 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 244 ; CHECK-BMI-NEXT: andl %edx, %edi 245 ; CHECK-BMI-NEXT: orl %edi, %eax 246 ; CHECK-BMI-NEXT: retq 247 %n0 = xor i32 %x, %y 248 %n1 = and i32 %mask, %n0 ; swapped 249 %r = xor i32 %y, %n1 ; swapped 250 ret i32 %r 251 } 252 define i32 @in_commutativity_1_0_0(i32 %x, i32 %y, i32 %mask) { 253 ; CHECK-NOBMI-LABEL: in_commutativity_1_0_0: 254 ; CHECK-NOBMI: # %bb.0: 255 ; CHECK-NOBMI-NEXT: xorl %edi, %esi 256 ; CHECK-NOBMI-NEXT: andl %edx, %esi 257 ; CHECK-NOBMI-NEXT: xorl %edi, %esi 258 ; CHECK-NOBMI-NEXT: movl %esi, %eax 259 ; CHECK-NOBMI-NEXT: retq 260 ; 261 ; CHECK-BMI-LABEL: in_commutativity_1_0_0: 262 ; CHECK-BMI: # %bb.0: 263 ; CHECK-BMI-NEXT: andnl %edi, %edx, %eax 264 ; CHECK-BMI-NEXT: andl %edx, %esi 265 ; CHECK-BMI-NEXT: orl %esi, %eax 266 ; CHECK-BMI-NEXT: retq 267 %n0 = xor i32 %x, %y 268 %n1 = and i32 %n0, %mask 269 %r = xor i32 %n1, %x ; %x instead of %y 270 ret i32 %r 271 } 272 define i32 @in_commutativity_1_0_1(i32 %x, i32 %y, i32 %mask) { 273 ; CHECK-NOBMI-LABEL: in_commutativity_1_0_1: 274 ; CHECK-NOBMI: # %bb.0: 275 ; CHECK-NOBMI-NEXT: xorl %edi, %esi 276 ; CHECK-NOBMI-NEXT: andl %edx, %esi 277 ; CHECK-NOBMI-NEXT: xorl %edi, %esi 278 ; CHECK-NOBMI-NEXT: movl %esi, %eax 279 ; CHECK-NOBMI-NEXT: retq 280 ; 281 ; CHECK-BMI-LABEL: in_commutativity_1_0_1: 282 ; CHECK-BMI: # %bb.0: 283 ; CHECK-BMI-NEXT: andnl %edi, %edx, %eax 284 ; CHECK-BMI-NEXT: andl %edx, %esi 285 ; CHECK-BMI-NEXT: orl %esi, %eax 286 ; CHECK-BMI-NEXT: retq 287 %n0 = xor i32 %x, %y 288 %n1 = and i32 %mask, %n0 ; swapped 289 %r = xor i32 %n1, %x ; %x instead of %y 290 ret i32 %r 291 } 292 define i32 @in_commutativity_1_1_0(i32 %x, i32 %y, i32 %mask) { 293 ; CHECK-NOBMI-LABEL: in_commutativity_1_1_0: 294 ; CHECK-NOBMI: # %bb.0: 295 ; CHECK-NOBMI-NEXT: xorl %edi, %esi 296 ; CHECK-NOBMI-NEXT: andl %edx, %esi 297 ; CHECK-NOBMI-NEXT: xorl %edi, %esi 298 ; CHECK-NOBMI-NEXT: movl %esi, %eax 299 ; CHECK-NOBMI-NEXT: retq 300 ; 301 ; CHECK-BMI-LABEL: in_commutativity_1_1_0: 302 ; CHECK-BMI: # %bb.0: 303 ; CHECK-BMI-NEXT: andnl %edi, %edx, %eax 304 ; CHECK-BMI-NEXT: andl %edx, %esi 305 ; CHECK-BMI-NEXT: orl %esi, %eax 306 ; CHECK-BMI-NEXT: retq 307 %n0 = xor i32 %x, %y 308 %n1 = and i32 %n0, %mask 309 %r = xor i32 %x, %n1 ; swapped, %x instead of %y 310 ret i32 %r 311 } 312 define i32 @in_commutativity_1_1_1(i32 %x, i32 %y, i32 %mask) { 313 ; CHECK-NOBMI-LABEL: in_commutativity_1_1_1: 314 ; CHECK-NOBMI: # %bb.0: 315 ; CHECK-NOBMI-NEXT: xorl %edi, %esi 316 ; CHECK-NOBMI-NEXT: andl %edx, %esi 317 ; CHECK-NOBMI-NEXT: xorl %edi, %esi 318 ; CHECK-NOBMI-NEXT: movl %esi, %eax 319 ; CHECK-NOBMI-NEXT: retq 320 ; 321 ; CHECK-BMI-LABEL: in_commutativity_1_1_1: 322 ; CHECK-BMI: # %bb.0: 323 ; CHECK-BMI-NEXT: andnl %edi, %edx, %eax 324 ; CHECK-BMI-NEXT: andl %edx, %esi 325 ; CHECK-BMI-NEXT: orl %esi, %eax 326 ; CHECK-BMI-NEXT: retq 327 %n0 = xor i32 %x, %y 328 %n1 = and i32 %mask, %n0 ; swapped 329 %r = xor i32 %x, %n1 ; swapped, %x instead of %y 330 ret i32 %r 331 } 332 ; ============================================================================ ; 333 ; Y is an 'and' too. 334 ; ============================================================================ ; 335 define i32 @in_complex_y0(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) { 336 ; CHECK-NOBMI-LABEL: in_complex_y0: 337 ; CHECK-NOBMI: # %bb.0: 338 ; CHECK-NOBMI-NEXT: andl %edx, %esi 339 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 340 ; CHECK-NOBMI-NEXT: andl %ecx, %edi 341 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 342 ; CHECK-NOBMI-NEXT: movl %edi, %eax 343 ; CHECK-NOBMI-NEXT: retq 344 ; 345 ; CHECK-BMI-LABEL: in_complex_y0: 346 ; CHECK-BMI: # %bb.0: 347 ; CHECK-BMI-NEXT: andl %edx, %esi 348 ; CHECK-BMI-NEXT: andl %ecx, %edi 349 ; CHECK-BMI-NEXT: andnl %esi, %ecx, %eax 350 ; CHECK-BMI-NEXT: orl %edi, %eax 351 ; CHECK-BMI-NEXT: retq 352 %y = and i32 %y_hi, %y_low 353 %n0 = xor i32 %x, %y 354 %n1 = and i32 %n0, %mask 355 %r = xor i32 %n1, %y 356 ret i32 %r 357 } 358 define i32 @in_complex_y1(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) { 359 ; CHECK-NOBMI-LABEL: in_complex_y1: 360 ; CHECK-NOBMI: # %bb.0: 361 ; CHECK-NOBMI-NEXT: andl %edx, %esi 362 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 363 ; CHECK-NOBMI-NEXT: andl %ecx, %edi 364 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 365 ; CHECK-NOBMI-NEXT: movl %edi, %eax 366 ; CHECK-NOBMI-NEXT: retq 367 ; 368 ; CHECK-BMI-LABEL: in_complex_y1: 369 ; CHECK-BMI: # %bb.0: 370 ; CHECK-BMI-NEXT: andl %edx, %esi 371 ; CHECK-BMI-NEXT: andl %ecx, %edi 372 ; CHECK-BMI-NEXT: andnl %esi, %ecx, %eax 373 ; CHECK-BMI-NEXT: orl %edi, %eax 374 ; CHECK-BMI-NEXT: retq 375 %y = and i32 %y_hi, %y_low 376 %n0 = xor i32 %x, %y 377 %n1 = and i32 %n0, %mask 378 %r = xor i32 %y, %n1 379 ret i32 %r 380 } 381 ; ============================================================================ ; 382 ; M is an 'xor' too. 383 ; ============================================================================ ; 384 define i32 @in_complex_m0(i32 %x, i32 %y, i32 %m_a, i32 %m_b) { 385 ; CHECK-NOBMI-LABEL: in_complex_m0: 386 ; CHECK-NOBMI: # %bb.0: 387 ; CHECK-NOBMI-NEXT: xorl %ecx, %edx 388 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 389 ; CHECK-NOBMI-NEXT: andl %edx, %edi 390 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 391 ; CHECK-NOBMI-NEXT: movl %edi, %eax 392 ; CHECK-NOBMI-NEXT: retq 393 ; 394 ; CHECK-BMI-LABEL: in_complex_m0: 395 ; CHECK-BMI: # %bb.0: 396 ; CHECK-BMI-NEXT: xorl %ecx, %edx 397 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 398 ; CHECK-BMI-NEXT: andl %edi, %edx 399 ; CHECK-BMI-NEXT: orl %edx, %eax 400 ; CHECK-BMI-NEXT: retq 401 %mask = xor i32 %m_a, %m_b 402 %n0 = xor i32 %x, %y 403 %n1 = and i32 %n0, %mask 404 %r = xor i32 %n1, %y 405 ret i32 %r 406 } 407 define i32 @in_complex_m1(i32 %x, i32 %y, i32 %m_a, i32 %m_b) { 408 ; CHECK-NOBMI-LABEL: in_complex_m1: 409 ; CHECK-NOBMI: # %bb.0: 410 ; CHECK-NOBMI-NEXT: xorl %ecx, %edx 411 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 412 ; CHECK-NOBMI-NEXT: andl %edx, %edi 413 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 414 ; CHECK-NOBMI-NEXT: movl %edi, %eax 415 ; CHECK-NOBMI-NEXT: retq 416 ; 417 ; CHECK-BMI-LABEL: in_complex_m1: 418 ; CHECK-BMI: # %bb.0: 419 ; CHECK-BMI-NEXT: xorl %ecx, %edx 420 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 421 ; CHECK-BMI-NEXT: andl %edi, %edx 422 ; CHECK-BMI-NEXT: orl %edx, %eax 423 ; CHECK-BMI-NEXT: retq 424 %mask = xor i32 %m_a, %m_b 425 %n0 = xor i32 %x, %y 426 %n1 = and i32 %mask, %n0 427 %r = xor i32 %n1, %y 428 ret i32 %r 429 } 430 ; ============================================================================ ; 431 ; Both Y and M are complex. 432 ; ============================================================================ ; 433 define i32 @in_complex_y0_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 434 ; CHECK-NOBMI-LABEL: in_complex_y0_m0: 435 ; CHECK-NOBMI: # %bb.0: 436 ; CHECK-NOBMI-NEXT: andl %edx, %esi 437 ; CHECK-NOBMI-NEXT: xorl %r8d, %ecx 438 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 439 ; CHECK-NOBMI-NEXT: andl %ecx, %edi 440 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 441 ; CHECK-NOBMI-NEXT: movl %edi, %eax 442 ; CHECK-NOBMI-NEXT: retq 443 ; 444 ; CHECK-BMI-LABEL: in_complex_y0_m0: 445 ; CHECK-BMI: # %bb.0: 446 ; CHECK-BMI-NEXT: andl %edx, %esi 447 ; CHECK-BMI-NEXT: xorl %r8d, %ecx 448 ; CHECK-BMI-NEXT: andnl %esi, %ecx, %eax 449 ; CHECK-BMI-NEXT: andl %edi, %ecx 450 ; CHECK-BMI-NEXT: orl %ecx, %eax 451 ; CHECK-BMI-NEXT: retq 452 %y = and i32 %y_hi, %y_low 453 %mask = xor i32 %m_a, %m_b 454 %n0 = xor i32 %x, %y 455 %n1 = and i32 %n0, %mask 456 %r = xor i32 %n1, %y 457 ret i32 %r 458 } 459 define i32 @in_complex_y1_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 460 ; CHECK-NOBMI-LABEL: in_complex_y1_m0: 461 ; CHECK-NOBMI: # %bb.0: 462 ; CHECK-NOBMI-NEXT: andl %edx, %esi 463 ; CHECK-NOBMI-NEXT: xorl %r8d, %ecx 464 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 465 ; CHECK-NOBMI-NEXT: andl %ecx, %edi 466 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 467 ; CHECK-NOBMI-NEXT: movl %edi, %eax 468 ; CHECK-NOBMI-NEXT: retq 469 ; 470 ; CHECK-BMI-LABEL: in_complex_y1_m0: 471 ; CHECK-BMI: # %bb.0: 472 ; CHECK-BMI-NEXT: andl %edx, %esi 473 ; CHECK-BMI-NEXT: xorl %r8d, %ecx 474 ; CHECK-BMI-NEXT: andnl %esi, %ecx, %eax 475 ; CHECK-BMI-NEXT: andl %edi, %ecx 476 ; CHECK-BMI-NEXT: orl %ecx, %eax 477 ; CHECK-BMI-NEXT: retq 478 %y = and i32 %y_hi, %y_low 479 %mask = xor i32 %m_a, %m_b 480 %n0 = xor i32 %x, %y 481 %n1 = and i32 %n0, %mask 482 %r = xor i32 %y, %n1 483 ret i32 %r 484 } 485 define i32 @in_complex_y0_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 486 ; CHECK-NOBMI-LABEL: in_complex_y0_m1: 487 ; CHECK-NOBMI: # %bb.0: 488 ; CHECK-NOBMI-NEXT: andl %edx, %esi 489 ; CHECK-NOBMI-NEXT: xorl %r8d, %ecx 490 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 491 ; CHECK-NOBMI-NEXT: andl %ecx, %edi 492 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 493 ; CHECK-NOBMI-NEXT: movl %edi, %eax 494 ; CHECK-NOBMI-NEXT: retq 495 ; 496 ; CHECK-BMI-LABEL: in_complex_y0_m1: 497 ; CHECK-BMI: # %bb.0: 498 ; CHECK-BMI-NEXT: andl %edx, %esi 499 ; CHECK-BMI-NEXT: xorl %r8d, %ecx 500 ; CHECK-BMI-NEXT: andnl %esi, %ecx, %eax 501 ; CHECK-BMI-NEXT: andl %edi, %ecx 502 ; CHECK-BMI-NEXT: orl %ecx, %eax 503 ; CHECK-BMI-NEXT: retq 504 %y = and i32 %y_hi, %y_low 505 %mask = xor i32 %m_a, %m_b 506 %n0 = xor i32 %x, %y 507 %n1 = and i32 %mask, %n0 508 %r = xor i32 %n1, %y 509 ret i32 %r 510 } 511 define i32 @in_complex_y1_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 512 ; CHECK-NOBMI-LABEL: in_complex_y1_m1: 513 ; CHECK-NOBMI: # %bb.0: 514 ; CHECK-NOBMI-NEXT: andl %edx, %esi 515 ; CHECK-NOBMI-NEXT: xorl %r8d, %ecx 516 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 517 ; CHECK-NOBMI-NEXT: andl %ecx, %edi 518 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 519 ; CHECK-NOBMI-NEXT: movl %edi, %eax 520 ; CHECK-NOBMI-NEXT: retq 521 ; 522 ; CHECK-BMI-LABEL: in_complex_y1_m1: 523 ; CHECK-BMI: # %bb.0: 524 ; CHECK-BMI-NEXT: andl %edx, %esi 525 ; CHECK-BMI-NEXT: xorl %r8d, %ecx 526 ; CHECK-BMI-NEXT: andnl %esi, %ecx, %eax 527 ; CHECK-BMI-NEXT: andl %edi, %ecx 528 ; CHECK-BMI-NEXT: orl %ecx, %eax 529 ; CHECK-BMI-NEXT: retq 530 %y = and i32 %y_hi, %y_low 531 %mask = xor i32 %m_a, %m_b 532 %n0 = xor i32 %x, %y 533 %n1 = and i32 %mask, %n0 534 %r = xor i32 %y, %n1 535 ret i32 %r 536 } 537 ; ============================================================================ ; 538 ; Various cases with %x and/or %y being a constant 539 ; ============================================================================ ; 540 define i32 @out_constant_varx_mone(i32 %x, i32 %y, i32 %mask) { 541 ; CHECK-NOBMI-LABEL: out_constant_varx_mone: 542 ; CHECK-NOBMI: # %bb.0: 543 ; CHECK-NOBMI-NEXT: andl %edx, %edi 544 ; CHECK-NOBMI-NEXT: notl %edx 545 ; CHECK-NOBMI-NEXT: orl %edx, %edi 546 ; CHECK-NOBMI-NEXT: movl %edi, %eax 547 ; CHECK-NOBMI-NEXT: retq 548 ; 549 ; CHECK-BMI-LABEL: out_constant_varx_mone: 550 ; CHECK-BMI: # %bb.0: 551 ; CHECK-BMI-NEXT: andl %edx, %edi 552 ; CHECK-BMI-NEXT: notl %edx 553 ; CHECK-BMI-NEXT: orl %edx, %edi 554 ; CHECK-BMI-NEXT: movl %edi, %eax 555 ; CHECK-BMI-NEXT: retq 556 %notmask = xor i32 %mask, -1 557 %mx = and i32 %mask, %x 558 %my = and i32 %notmask, -1 559 %r = or i32 %mx, %my 560 ret i32 %r 561 } 562 define i32 @in_constant_varx_mone(i32 %x, i32 %y, i32 %mask) { 563 ; CHECK-NOBMI-LABEL: in_constant_varx_mone: 564 ; CHECK-NOBMI: # %bb.0: 565 ; CHECK-NOBMI-NEXT: notl %edi 566 ; CHECK-NOBMI-NEXT: andl %edx, %edi 567 ; CHECK-NOBMI-NEXT: notl %edi 568 ; CHECK-NOBMI-NEXT: movl %edi, %eax 569 ; CHECK-NOBMI-NEXT: retq 570 ; 571 ; CHECK-BMI-LABEL: in_constant_varx_mone: 572 ; CHECK-BMI: # %bb.0: 573 ; CHECK-BMI-NEXT: andnl %edx, %edi, %eax 574 ; CHECK-BMI-NEXT: notl %eax 575 ; CHECK-BMI-NEXT: retq 576 %n0 = xor i32 %x, -1 ; %x 577 %n1 = and i32 %n0, %mask 578 %r = xor i32 %n1, -1 579 ret i32 %r 580 } 581 ; This is not a canonical form. Testing for completeness only. 582 define i32 @out_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) { 583 ; CHECK-NOBMI-LABEL: out_constant_varx_mone_invmask: 584 ; CHECK-NOBMI: # %bb.0: 585 ; CHECK-NOBMI-NEXT: movl %edx, %eax 586 ; CHECK-NOBMI-NEXT: notl %eax 587 ; CHECK-NOBMI-NEXT: andl %edi, %eax 588 ; CHECK-NOBMI-NEXT: orl %edx, %eax 589 ; CHECK-NOBMI-NEXT: retq 590 ; 591 ; CHECK-BMI-LABEL: out_constant_varx_mone_invmask: 592 ; CHECK-BMI: # %bb.0: 593 ; CHECK-BMI-NEXT: andnl %edi, %edx, %eax 594 ; CHECK-BMI-NEXT: orl %edx, %eax 595 ; CHECK-BMI-NEXT: retq 596 %notmask = xor i32 %mask, -1 597 %mx = and i32 %notmask, %x 598 %my = and i32 %mask, -1 599 %r = or i32 %mx, %my 600 ret i32 %r 601 } 602 ; This is not a canonical form. Testing for completeness only. 603 define i32 @in_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) { 604 ; CHECK-NOBMI-LABEL: in_constant_varx_mone_invmask: 605 ; CHECK-NOBMI: # %bb.0: 606 ; CHECK-NOBMI-NEXT: notl %edx 607 ; CHECK-NOBMI-NEXT: notl %edi 608 ; CHECK-NOBMI-NEXT: andl %edx, %edi 609 ; CHECK-NOBMI-NEXT: notl %edi 610 ; CHECK-NOBMI-NEXT: movl %edi, %eax 611 ; CHECK-NOBMI-NEXT: retq 612 ; 613 ; CHECK-BMI-LABEL: in_constant_varx_mone_invmask: 614 ; CHECK-BMI: # %bb.0: 615 ; CHECK-BMI-NEXT: notl %edx 616 ; CHECK-BMI-NEXT: andnl %edx, %edi, %eax 617 ; CHECK-BMI-NEXT: notl %eax 618 ; CHECK-BMI-NEXT: retq 619 %notmask = xor i32 %mask, -1 620 %n0 = xor i32 %x, -1 ; %x 621 %n1 = and i32 %n0, %notmask 622 %r = xor i32 %n1, -1 623 ret i32 %r 624 } 625 define i32 @out_constant_varx_42(i32 %x, i32 %y, i32 %mask) { 626 ; CHECK-NOBMI-LABEL: out_constant_varx_42: 627 ; CHECK-NOBMI: # %bb.0: 628 ; CHECK-NOBMI-NEXT: andl %edx, %edi 629 ; CHECK-NOBMI-NEXT: movl %edx, %eax 630 ; CHECK-NOBMI-NEXT: notl %eax 631 ; CHECK-NOBMI-NEXT: andl $42, %eax 632 ; CHECK-NOBMI-NEXT: orl %edi, %eax 633 ; CHECK-NOBMI-NEXT: retq 634 ; 635 ; CHECK-BMI-LABEL: out_constant_varx_42: 636 ; CHECK-BMI: # %bb.0: 637 ; CHECK-BMI-NEXT: andl %edx, %edi 638 ; CHECK-BMI-NEXT: movl %edx, %eax 639 ; CHECK-BMI-NEXT: notl %eax 640 ; CHECK-BMI-NEXT: andl $42, %eax 641 ; CHECK-BMI-NEXT: orl %edi, %eax 642 ; CHECK-BMI-NEXT: retq 643 %notmask = xor i32 %mask, -1 644 %mx = and i32 %mask, %x 645 %my = and i32 %notmask, 42 646 %r = or i32 %mx, %my 647 ret i32 %r 648 } 649 define i32 @in_constant_varx_42(i32 %x, i32 %y, i32 %mask) { 650 ; CHECK-NOBMI-LABEL: in_constant_varx_42: 651 ; CHECK-NOBMI: # %bb.0: 652 ; CHECK-NOBMI-NEXT: xorl $42, %edi 653 ; CHECK-NOBMI-NEXT: andl %edx, %edi 654 ; CHECK-NOBMI-NEXT: xorl $42, %edi 655 ; CHECK-NOBMI-NEXT: movl %edi, %eax 656 ; CHECK-NOBMI-NEXT: retq 657 ; 658 ; CHECK-BMI-LABEL: in_constant_varx_42: 659 ; CHECK-BMI: # %bb.0: 660 ; CHECK-BMI-NEXT: andnl %edx, %edi, %eax 661 ; CHECK-BMI-NEXT: orl $42, %edx 662 ; CHECK-BMI-NEXT: andnl %edx, %eax, %eax 663 ; CHECK-BMI-NEXT: retq 664 %n0 = xor i32 %x, 42 ; %x 665 %n1 = and i32 %n0, %mask 666 %r = xor i32 %n1, 42 667 ret i32 %r 668 } 669 ; This is not a canonical form. Testing for completeness only. 670 define i32 @out_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) { 671 ; CHECK-NOBMI-LABEL: out_constant_varx_42_invmask: 672 ; CHECK-NOBMI: # %bb.0: 673 ; CHECK-NOBMI-NEXT: movl %edx, %eax 674 ; CHECK-NOBMI-NEXT: notl %eax 675 ; CHECK-NOBMI-NEXT: andl %edi, %eax 676 ; CHECK-NOBMI-NEXT: andl $42, %edx 677 ; CHECK-NOBMI-NEXT: orl %eax, %edx 678 ; CHECK-NOBMI-NEXT: movl %edx, %eax 679 ; CHECK-NOBMI-NEXT: retq 680 ; 681 ; CHECK-BMI-LABEL: out_constant_varx_42_invmask: 682 ; CHECK-BMI: # %bb.0: 683 ; CHECK-BMI-NEXT: andnl %edi, %edx, %eax 684 ; CHECK-BMI-NEXT: andl $42, %edx 685 ; CHECK-BMI-NEXT: orl %edx, %eax 686 ; CHECK-BMI-NEXT: retq 687 %notmask = xor i32 %mask, -1 688 %mx = and i32 %notmask, %x 689 %my = and i32 %mask, 42 690 %r = or i32 %mx, %my 691 ret i32 %r 692 } 693 ; This is not a canonical form. Testing for completeness only. 694 define i32 @in_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) { 695 ; CHECK-NOBMI-LABEL: in_constant_varx_42_invmask: 696 ; CHECK-NOBMI: # %bb.0: 697 ; CHECK-NOBMI-NEXT: notl %edx 698 ; CHECK-NOBMI-NEXT: xorl $42, %edi 699 ; CHECK-NOBMI-NEXT: andl %edx, %edi 700 ; CHECK-NOBMI-NEXT: xorl $42, %edi 701 ; CHECK-NOBMI-NEXT: movl %edi, %eax 702 ; CHECK-NOBMI-NEXT: retq 703 ; 704 ; CHECK-BMI-LABEL: in_constant_varx_42_invmask: 705 ; CHECK-BMI: # %bb.0: 706 ; CHECK-BMI-NEXT: notl %edx 707 ; CHECK-BMI-NEXT: andnl %edx, %edi, %eax 708 ; CHECK-BMI-NEXT: orl $42, %edx 709 ; CHECK-BMI-NEXT: andnl %edx, %eax, %eax 710 ; CHECK-BMI-NEXT: retq 711 %notmask = xor i32 %mask, -1 712 %n0 = xor i32 %x, 42 ; %x 713 %n1 = and i32 %n0, %notmask 714 %r = xor i32 %n1, 42 715 ret i32 %r 716 } 717 define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) { 718 ; CHECK-NOBMI-LABEL: out_constant_mone_vary: 719 ; CHECK-NOBMI: # %bb.0: 720 ; CHECK-NOBMI-NEXT: movl %edx, %eax 721 ; CHECK-NOBMI-NEXT: notl %eax 722 ; CHECK-NOBMI-NEXT: andl %esi, %eax 723 ; CHECK-NOBMI-NEXT: orl %edx, %eax 724 ; CHECK-NOBMI-NEXT: retq 725 ; 726 ; CHECK-BMI-LABEL: out_constant_mone_vary: 727 ; CHECK-BMI: # %bb.0: 728 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 729 ; CHECK-BMI-NEXT: orl %edx, %eax 730 ; CHECK-BMI-NEXT: retq 731 %notmask = xor i32 %mask, -1 732 %mx = and i32 %mask, -1 733 %my = and i32 %notmask, %y 734 %r = or i32 %mx, %my 735 ret i32 %r 736 } 737 define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) { 738 ; CHECK-NOBMI-LABEL: in_constant_mone_vary: 739 ; CHECK-NOBMI: # %bb.0: 740 ; CHECK-NOBMI-NEXT: movl %esi, %eax 741 ; CHECK-NOBMI-NEXT: notl %eax 742 ; CHECK-NOBMI-NEXT: andl %edx, %eax 743 ; CHECK-NOBMI-NEXT: xorl %esi, %eax 744 ; CHECK-NOBMI-NEXT: retq 745 ; 746 ; CHECK-BMI-LABEL: in_constant_mone_vary: 747 ; CHECK-BMI: # %bb.0: 748 ; CHECK-BMI-NEXT: andnl %edx, %esi, %eax 749 ; CHECK-BMI-NEXT: xorl %esi, %eax 750 ; CHECK-BMI-NEXT: retq 751 %n0 = xor i32 -1, %y ; %x 752 %n1 = and i32 %n0, %mask 753 %r = xor i32 %n1, %y 754 ret i32 %r 755 } 756 ; This is not a canonical form. Testing for completeness only. 757 define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { 758 ; CHECK-NOBMI-LABEL: out_constant_mone_vary_invmask: 759 ; CHECK-NOBMI: # %bb.0: 760 ; CHECK-NOBMI-NEXT: andl %edx, %esi 761 ; CHECK-NOBMI-NEXT: notl %edx 762 ; CHECK-NOBMI-NEXT: orl %edx, %esi 763 ; CHECK-NOBMI-NEXT: movl %esi, %eax 764 ; CHECK-NOBMI-NEXT: retq 765 ; 766 ; CHECK-BMI-LABEL: out_constant_mone_vary_invmask: 767 ; CHECK-BMI: # %bb.0: 768 ; CHECK-BMI-NEXT: andl %edx, %esi 769 ; CHECK-BMI-NEXT: notl %edx 770 ; CHECK-BMI-NEXT: orl %edx, %esi 771 ; CHECK-BMI-NEXT: movl %esi, %eax 772 ; CHECK-BMI-NEXT: retq 773 %notmask = xor i32 %mask, -1 774 %mx = and i32 %notmask, -1 775 %my = and i32 %mask, %y 776 %r = or i32 %mx, %my 777 ret i32 %r 778 } 779 ; This is not a canonical form. Testing for completeness only. 780 define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { 781 ; CHECK-NOBMI-LABEL: in_constant_mone_vary_invmask: 782 ; CHECK-NOBMI: # %bb.0: 783 ; CHECK-NOBMI-NEXT: notl %edx 784 ; CHECK-NOBMI-NEXT: movl %esi, %eax 785 ; CHECK-NOBMI-NEXT: notl %eax 786 ; CHECK-NOBMI-NEXT: andl %edx, %eax 787 ; CHECK-NOBMI-NEXT: xorl %esi, %eax 788 ; CHECK-NOBMI-NEXT: retq 789 ; 790 ; CHECK-BMI-LABEL: in_constant_mone_vary_invmask: 791 ; CHECK-BMI: # %bb.0: 792 ; CHECK-BMI-NEXT: notl %edx 793 ; CHECK-BMI-NEXT: andnl %edx, %esi, %eax 794 ; CHECK-BMI-NEXT: xorl %esi, %eax 795 ; CHECK-BMI-NEXT: retq 796 %notmask = xor i32 %mask, -1 797 %n0 = xor i32 -1, %y ; %x 798 %n1 = and i32 %n0, %notmask 799 %r = xor i32 %n1, %y 800 ret i32 %r 801 } 802 define i32 @out_constant_42_vary(i32 %x, i32 %y, i32 %mask) { 803 ; CHECK-NOBMI-LABEL: out_constant_42_vary: 804 ; CHECK-NOBMI: # %bb.0: 805 ; CHECK-NOBMI-NEXT: movl %edx, %eax 806 ; CHECK-NOBMI-NEXT: notl %eax 807 ; CHECK-NOBMI-NEXT: andl $42, %edx 808 ; CHECK-NOBMI-NEXT: andl %esi, %eax 809 ; CHECK-NOBMI-NEXT: orl %edx, %eax 810 ; CHECK-NOBMI-NEXT: retq 811 ; 812 ; CHECK-BMI-LABEL: out_constant_42_vary: 813 ; CHECK-BMI: # %bb.0: 814 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 815 ; CHECK-BMI-NEXT: andl $42, %edx 816 ; CHECK-BMI-NEXT: orl %edx, %eax 817 ; CHECK-BMI-NEXT: retq 818 %notmask = xor i32 %mask, -1 819 %mx = and i32 %mask, 42 820 %my = and i32 %notmask, %y 821 %r = or i32 %mx, %my 822 ret i32 %r 823 } 824 define i32 @in_constant_42_vary(i32 %x, i32 %y, i32 %mask) { 825 ; CHECK-NOBMI-LABEL: in_constant_42_vary: 826 ; CHECK-NOBMI: # %bb.0: 827 ; CHECK-NOBMI-NEXT: movl %esi, %eax 828 ; CHECK-NOBMI-NEXT: xorl $42, %eax 829 ; CHECK-NOBMI-NEXT: andl %edx, %eax 830 ; CHECK-NOBMI-NEXT: xorl %esi, %eax 831 ; CHECK-NOBMI-NEXT: retq 832 ; 833 ; CHECK-BMI-LABEL: in_constant_42_vary: 834 ; CHECK-BMI: # %bb.0: 835 ; CHECK-BMI-NEXT: andnl %esi, %edx, %eax 836 ; CHECK-BMI-NEXT: andl $42, %edx 837 ; CHECK-BMI-NEXT: orl %edx, %eax 838 ; CHECK-BMI-NEXT: retq 839 %n0 = xor i32 42, %y ; %x 840 %n1 = and i32 %n0, %mask 841 %r = xor i32 %n1, %y 842 ret i32 %r 843 } 844 ; This is not a canonical form. Testing for completeness only. 845 define i32 @out_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) { 846 ; CHECK-NOBMI-LABEL: out_constant_42_vary_invmask: 847 ; CHECK-NOBMI: # %bb.0: 848 ; CHECK-NOBMI-NEXT: andl %edx, %esi 849 ; CHECK-NOBMI-NEXT: notl %edx 850 ; CHECK-NOBMI-NEXT: andl $42, %edx 851 ; CHECK-NOBMI-NEXT: orl %edx, %esi 852 ; CHECK-NOBMI-NEXT: movl %esi, %eax 853 ; CHECK-NOBMI-NEXT: retq 854 ; 855 ; CHECK-BMI-LABEL: out_constant_42_vary_invmask: 856 ; CHECK-BMI: # %bb.0: 857 ; CHECK-BMI-NEXT: andl %edx, %esi 858 ; CHECK-BMI-NEXT: notl %edx 859 ; CHECK-BMI-NEXT: andl $42, %edx 860 ; CHECK-BMI-NEXT: orl %edx, %esi 861 ; CHECK-BMI-NEXT: movl %esi, %eax 862 ; CHECK-BMI-NEXT: retq 863 %notmask = xor i32 %mask, -1 864 %mx = and i32 %notmask, 42 865 %my = and i32 %mask, %y 866 %r = or i32 %mx, %my 867 ret i32 %r 868 } 869 ; This is not a canonical form. Testing for completeness only. 870 define i32 @in_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) { 871 ; CHECK-NOBMI-LABEL: in_constant_42_vary_invmask: 872 ; CHECK-NOBMI: # %bb.0: 873 ; CHECK-NOBMI-NEXT: notl %edx 874 ; CHECK-NOBMI-NEXT: movl %esi, %eax 875 ; CHECK-NOBMI-NEXT: xorl $42, %eax 876 ; CHECK-NOBMI-NEXT: andl %edx, %eax 877 ; CHECK-NOBMI-NEXT: xorl %esi, %eax 878 ; CHECK-NOBMI-NEXT: retq 879 ; 880 ; CHECK-BMI-LABEL: in_constant_42_vary_invmask: 881 ; CHECK-BMI: # %bb.0: 882 ; CHECK-BMI-NEXT: andl %edx, %esi 883 ; CHECK-BMI-NEXT: notl %edx 884 ; CHECK-BMI-NEXT: andl $42, %edx 885 ; CHECK-BMI-NEXT: orl %esi, %edx 886 ; CHECK-BMI-NEXT: movl %edx, %eax 887 ; CHECK-BMI-NEXT: retq 888 %notmask = xor i32 %mask, -1 889 %n0 = xor i32 42, %y ; %x 890 %n1 = and i32 %n0, %notmask 891 %r = xor i32 %n1, %y 892 ret i32 %r 893 } 894 ; ============================================================================ ; 895 ; Negative tests. Should not be folded. 896 ; ============================================================================ ; 897 ; Multi-use tests. 898 declare void @use32(i32) nounwind 899 define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { 900 ; CHECK-NOBMI-LABEL: in_multiuse_A: 901 ; CHECK-NOBMI: # %bb.0: 902 ; CHECK-NOBMI-NEXT: pushq %rbp 903 ; CHECK-NOBMI-NEXT: pushq %rbx 904 ; CHECK-NOBMI-NEXT: pushq %rax 905 ; CHECK-NOBMI-NEXT: movl %esi, %ebx 906 ; CHECK-NOBMI-NEXT: movl %edi, %ebp 907 ; CHECK-NOBMI-NEXT: xorl %esi, %ebp 908 ; CHECK-NOBMI-NEXT: andl %ecx, %ebp 909 ; CHECK-NOBMI-NEXT: movl %ebp, %edi 910 ; CHECK-NOBMI-NEXT: callq use32 911 ; CHECK-NOBMI-NEXT: xorl %ebx, %ebp 912 ; CHECK-NOBMI-NEXT: movl %ebp, %eax 913 ; CHECK-NOBMI-NEXT: addq $8, %rsp 914 ; CHECK-NOBMI-NEXT: popq %rbx 915 ; CHECK-NOBMI-NEXT: popq %rbp 916 ; CHECK-NOBMI-NEXT: retq 917 ; 918 ; CHECK-BMI-LABEL: in_multiuse_A: 919 ; CHECK-BMI: # %bb.0: 920 ; CHECK-BMI-NEXT: pushq %rbp 921 ; CHECK-BMI-NEXT: pushq %rbx 922 ; CHECK-BMI-NEXT: pushq %rax 923 ; CHECK-BMI-NEXT: movl %esi, %ebx 924 ; CHECK-BMI-NEXT: movl %edi, %ebp 925 ; CHECK-BMI-NEXT: xorl %esi, %ebp 926 ; CHECK-BMI-NEXT: andl %ecx, %ebp 927 ; CHECK-BMI-NEXT: movl %ebp, %edi 928 ; CHECK-BMI-NEXT: callq use32 929 ; CHECK-BMI-NEXT: xorl %ebx, %ebp 930 ; CHECK-BMI-NEXT: movl %ebp, %eax 931 ; CHECK-BMI-NEXT: addq $8, %rsp 932 ; CHECK-BMI-NEXT: popq %rbx 933 ; CHECK-BMI-NEXT: popq %rbp 934 ; CHECK-BMI-NEXT: retq 935 %n0 = xor i32 %x, %y 936 %n1 = and i32 %n0, %mask 937 call void @use32(i32 %n1) 938 %r = xor i32 %n1, %y 939 ret i32 %r 940 } 941 define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { 942 ; CHECK-NOBMI-LABEL: in_multiuse_B: 943 ; CHECK-NOBMI: # %bb.0: 944 ; CHECK-NOBMI-NEXT: pushq %rbp 945 ; CHECK-NOBMI-NEXT: pushq %rbx 946 ; CHECK-NOBMI-NEXT: pushq %rax 947 ; CHECK-NOBMI-NEXT: movl %ecx, %ebx 948 ; CHECK-NOBMI-NEXT: movl %esi, %ebp 949 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 950 ; CHECK-NOBMI-NEXT: andl %edi, %ebx 951 ; CHECK-NOBMI-NEXT: callq use32 952 ; CHECK-NOBMI-NEXT: xorl %ebp, %ebx 953 ; CHECK-NOBMI-NEXT: movl %ebx, %eax 954 ; CHECK-NOBMI-NEXT: addq $8, %rsp 955 ; CHECK-NOBMI-NEXT: popq %rbx 956 ; CHECK-NOBMI-NEXT: popq %rbp 957 ; CHECK-NOBMI-NEXT: retq 958 ; 959 ; CHECK-BMI-LABEL: in_multiuse_B: 960 ; CHECK-BMI: # %bb.0: 961 ; CHECK-BMI-NEXT: pushq %rbp 962 ; CHECK-BMI-NEXT: pushq %rbx 963 ; CHECK-BMI-NEXT: pushq %rax 964 ; CHECK-BMI-NEXT: movl %ecx, %ebx 965 ; CHECK-BMI-NEXT: movl %esi, %ebp 966 ; CHECK-BMI-NEXT: xorl %esi, %edi 967 ; CHECK-BMI-NEXT: andl %edi, %ebx 968 ; CHECK-BMI-NEXT: callq use32 969 ; CHECK-BMI-NEXT: xorl %ebp, %ebx 970 ; CHECK-BMI-NEXT: movl %ebx, %eax 971 ; CHECK-BMI-NEXT: addq $8, %rsp 972 ; CHECK-BMI-NEXT: popq %rbx 973 ; CHECK-BMI-NEXT: popq %rbp 974 ; CHECK-BMI-NEXT: retq 975 %n0 = xor i32 %x, %y 976 %n1 = and i32 %n0, %mask 977 call void @use32(i32 %n0) 978 %r = xor i32 %n1, %y 979 ret i32 %r 980 } 981 ; Various bad variants 982 define i32 @n0_badmask(i32 %x, i32 %y, i32 %mask, i32 %mask2) { 983 ; CHECK-NOBMI-LABEL: n0_badmask: 984 ; CHECK-NOBMI: # %bb.0: 985 ; CHECK-NOBMI-NEXT: andl %edx, %edi 986 ; CHECK-NOBMI-NEXT: notl %ecx 987 ; CHECK-NOBMI-NEXT: andl %esi, %ecx 988 ; CHECK-NOBMI-NEXT: orl %edi, %ecx 989 ; CHECK-NOBMI-NEXT: movl %ecx, %eax 990 ; CHECK-NOBMI-NEXT: retq 991 ; 992 ; CHECK-BMI-LABEL: n0_badmask: 993 ; CHECK-BMI: # %bb.0: 994 ; CHECK-BMI-NEXT: andl %edx, %edi 995 ; CHECK-BMI-NEXT: andnl %esi, %ecx, %eax 996 ; CHECK-BMI-NEXT: orl %edi, %eax 997 ; CHECK-BMI-NEXT: retq 998 %mx = and i32 %x, %mask 999 %notmask = xor i32 %mask2, -1 ; %mask2 instead of %mask 1000 %my = and i32 %y, %notmask 1001 %r = or i32 %mx, %my 1002 ret i32 %r 1003 } 1004 define i32 @n0_badxor(i32 %x, i32 %y, i32 %mask) { 1005 ; CHECK-NOBMI-LABEL: n0_badxor: 1006 ; CHECK-NOBMI: # %bb.0: 1007 ; CHECK-NOBMI-NEXT: andl %edx, %edi 1008 ; CHECK-NOBMI-NEXT: xorl $1, %edx 1009 ; CHECK-NOBMI-NEXT: andl %esi, %edx 1010 ; CHECK-NOBMI-NEXT: orl %edi, %edx 1011 ; CHECK-NOBMI-NEXT: movl %edx, %eax 1012 ; CHECK-NOBMI-NEXT: retq 1013 ; 1014 ; CHECK-BMI-LABEL: n0_badxor: 1015 ; CHECK-BMI: # %bb.0: 1016 ; CHECK-BMI-NEXT: andl %edx, %edi 1017 ; CHECK-BMI-NEXT: xorl $1, %edx 1018 ; CHECK-BMI-NEXT: andl %esi, %edx 1019 ; CHECK-BMI-NEXT: orl %edi, %edx 1020 ; CHECK-BMI-NEXT: movl %edx, %eax 1021 ; CHECK-BMI-NEXT: retq 1022 %mx = and i32 %x, %mask 1023 %notmask = xor i32 %mask, 1 ; instead of -1 1024 %my = and i32 %y, %notmask 1025 %r = or i32 %mx, %my 1026 ret i32 %r 1027 } 1028 define i32 @n1_thirdvar(i32 %x, i32 %y, i32 %z, i32 %mask) { 1029 ; CHECK-NOBMI-LABEL: n1_thirdvar: 1030 ; CHECK-NOBMI: # %bb.0: 1031 ; CHECK-NOBMI-NEXT: xorl %esi, %edi 1032 ; CHECK-NOBMI-NEXT: andl %ecx, %edi 1033 ; CHECK-NOBMI-NEXT: xorl %edx, %edi 1034 ; CHECK-NOBMI-NEXT: movl %edi, %eax 1035 ; CHECK-NOBMI-NEXT: retq 1036 ; 1037 ; CHECK-BMI-LABEL: n1_thirdvar: 1038 ; CHECK-BMI: # %bb.0: 1039 ; CHECK-BMI-NEXT: xorl %esi, %edi 1040 ; CHECK-BMI-NEXT: andl %ecx, %edi 1041 ; CHECK-BMI-NEXT: xorl %edx, %edi 1042 ; CHECK-BMI-NEXT: movl %edi, %eax 1043 ; CHECK-BMI-NEXT: retq 1044 %n0 = xor i32 %x, %y 1045 %n1 = and i32 %n0, %mask 1046 %r = xor i32 %n1, %z ; instead of %y 1047 ret i32 %r 1048 } 1049