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