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