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: 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 31define 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 55define 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 78define 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 104define 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 126define 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 148define 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 169define 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; ============================================================================ ; 192define 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} 212define 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} 232define 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} 252define 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} 272define 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} 292define 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} 312define 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; ============================================================================ ; 335define 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} 358define 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; ============================================================================ ; 384define 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} 407define 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; ============================================================================ ; 433define 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} 459define 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} 485define 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} 511define 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; ============================================================================ ; 540define 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} 562define 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. 582define 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. 603define 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} 625define 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} 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: 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. 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 %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. 694define 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} 717define 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} 737define 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. 757define 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. 780define 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} 802define 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} 824define 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. 845define 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. 870define 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. 898declare void @use32(i32) nounwind 899define 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} 941define 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 982define 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} 1004define 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} 1028define 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