1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s 3 4; https://bugs.llvm.org/show_bug.cgi?id=37104 5 6define i8 @out8(i8 %x, i8 %y, i8 %mask) { 7; CHECK-LABEL: out8: 8; CHECK: // %bb.0: 9; CHECK-NEXT: and w8, w0, w2 10; CHECK-NEXT: bic w9, w1, w2 11; CHECK-NEXT: orr w0, w8, w9 12; CHECK-NEXT: ret 13 %mx = and i8 %x, %mask 14 %notmask = xor i8 %mask, -1 15 %my = and i8 %y, %notmask 16 %r = or i8 %mx, %my 17 ret i8 %r 18} 19 20define i16 @out16(i16 %x, i16 %y, i16 %mask) { 21; CHECK-LABEL: out16: 22; CHECK: // %bb.0: 23; CHECK-NEXT: and w8, w0, w2 24; CHECK-NEXT: bic w9, w1, w2 25; CHECK-NEXT: orr w0, w8, w9 26; CHECK-NEXT: ret 27 %mx = and i16 %x, %mask 28 %notmask = xor i16 %mask, -1 29 %my = and i16 %y, %notmask 30 %r = or i16 %mx, %my 31 ret i16 %r 32} 33 34define i32 @out32(i32 %x, i32 %y, i32 %mask) { 35; CHECK-LABEL: out32: 36; CHECK: // %bb.0: 37; CHECK-NEXT: and w8, w0, w2 38; CHECK-NEXT: bic w9, w1, w2 39; CHECK-NEXT: orr w0, w8, w9 40; CHECK-NEXT: ret 41 %mx = and i32 %x, %mask 42 %notmask = xor i32 %mask, -1 43 %my = and i32 %y, %notmask 44 %r = or i32 %mx, %my 45 ret i32 %r 46} 47 48define i64 @out64(i64 %x, i64 %y, i64 %mask) { 49; CHECK-LABEL: out64: 50; CHECK: // %bb.0: 51; CHECK-NEXT: and x8, x0, x2 52; CHECK-NEXT: bic x9, x1, x2 53; CHECK-NEXT: orr x0, x8, x9 54; CHECK-NEXT: ret 55 %mx = and i64 %x, %mask 56 %notmask = xor i64 %mask, -1 57 %my = and i64 %y, %notmask 58 %r = or i64 %mx, %my 59 ret i64 %r 60} 61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 62; Should be the same as the previous one. 63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64 65define i8 @in8(i8 %x, i8 %y, i8 %mask) { 66; CHECK-LABEL: in8: 67; CHECK: // %bb.0: 68; CHECK-NEXT: and w8, w0, w2 69; CHECK-NEXT: bic w9, w1, w2 70; CHECK-NEXT: orr w0, w8, w9 71; CHECK-NEXT: ret 72 %n0 = xor i8 %x, %y 73 %n1 = and i8 %n0, %mask 74 %r = xor i8 %n1, %y 75 ret i8 %r 76} 77 78define i16 @in16(i16 %x, i16 %y, i16 %mask) { 79; CHECK-LABEL: in16: 80; CHECK: // %bb.0: 81; CHECK-NEXT: and w8, w0, w2 82; CHECK-NEXT: bic w9, w1, w2 83; CHECK-NEXT: orr w0, w8, w9 84; CHECK-NEXT: ret 85 %n0 = xor i16 %x, %y 86 %n1 = and i16 %n0, %mask 87 %r = xor i16 %n1, %y 88 ret i16 %r 89} 90 91define i32 @in32(i32 %x, i32 %y, i32 %mask) { 92; CHECK-LABEL: in32: 93; CHECK: // %bb.0: 94; CHECK-NEXT: bic w8, w1, w2 95; CHECK-NEXT: and w9, w0, w2 96; CHECK-NEXT: orr w0, w9, w8 97; CHECK-NEXT: ret 98 %n0 = xor i32 %x, %y 99 %n1 = and i32 %n0, %mask 100 %r = xor i32 %n1, %y 101 ret i32 %r 102} 103 104define i64 @in64(i64 %x, i64 %y, i64 %mask) { 105; CHECK-LABEL: in64: 106; CHECK: // %bb.0: 107; CHECK-NEXT: bic x8, x1, x2 108; CHECK-NEXT: and x9, x0, x2 109; CHECK-NEXT: orr x0, x9, x8 110; CHECK-NEXT: ret 111 %n0 = xor i64 %x, %y 112 %n1 = and i64 %n0, %mask 113 %r = xor i64 %n1, %y 114 ret i64 %r 115} 116; ============================================================================ ; 117; Commutativity tests. 118; ============================================================================ ; 119define i32 @in_commutativity_0_0_1(i32 %x, i32 %y, i32 %mask) { 120; CHECK-LABEL: in_commutativity_0_0_1: 121; CHECK: // %bb.0: 122; CHECK-NEXT: bic w8, w1, w2 123; CHECK-NEXT: and w9, w0, w2 124; CHECK-NEXT: orr w0, w9, w8 125; CHECK-NEXT: ret 126 %n0 = xor i32 %x, %y 127 %n1 = and i32 %mask, %n0 ; swapped 128 %r = xor i32 %n1, %y 129 ret i32 %r 130} 131define i32 @in_commutativity_0_1_0(i32 %x, i32 %y, i32 %mask) { 132; CHECK-LABEL: in_commutativity_0_1_0: 133; CHECK: // %bb.0: 134; CHECK-NEXT: bic w8, w1, w2 135; CHECK-NEXT: and w9, w0, w2 136; CHECK-NEXT: orr w0, w9, w8 137; CHECK-NEXT: ret 138 %n0 = xor i32 %x, %y 139 %n1 = and i32 %n0, %mask 140 %r = xor i32 %y, %n1 ; swapped 141 ret i32 %r 142} 143define i32 @in_commutativity_0_1_1(i32 %x, i32 %y, i32 %mask) { 144; CHECK-LABEL: in_commutativity_0_1_1: 145; CHECK: // %bb.0: 146; CHECK-NEXT: bic w8, w1, w2 147; CHECK-NEXT: and w9, w0, w2 148; CHECK-NEXT: orr w0, w9, w8 149; CHECK-NEXT: ret 150 %n0 = xor i32 %x, %y 151 %n1 = and i32 %mask, %n0 ; swapped 152 %r = xor i32 %y, %n1 ; swapped 153 ret i32 %r 154} 155define i32 @in_commutativity_1_0_0(i32 %x, i32 %y, i32 %mask) { 156; CHECK-LABEL: in_commutativity_1_0_0: 157; CHECK: // %bb.0: 158; CHECK-NEXT: bic w8, w0, w2 159; CHECK-NEXT: and w9, w1, w2 160; CHECK-NEXT: orr w0, w9, w8 161; CHECK-NEXT: ret 162 %n0 = xor i32 %x, %y 163 %n1 = and i32 %n0, %mask 164 %r = xor i32 %n1, %x ; %x instead of %y 165 ret i32 %r 166} 167define i32 @in_commutativity_1_0_1(i32 %x, i32 %y, i32 %mask) { 168; CHECK-LABEL: in_commutativity_1_0_1: 169; CHECK: // %bb.0: 170; CHECK-NEXT: bic w8, w0, w2 171; CHECK-NEXT: and w9, w1, w2 172; CHECK-NEXT: orr w0, w9, w8 173; CHECK-NEXT: ret 174 %n0 = xor i32 %x, %y 175 %n1 = and i32 %mask, %n0 ; swapped 176 %r = xor i32 %n1, %x ; %x instead of %y 177 ret i32 %r 178} 179define i32 @in_commutativity_1_1_0(i32 %x, i32 %y, i32 %mask) { 180; CHECK-LABEL: in_commutativity_1_1_0: 181; CHECK: // %bb.0: 182; CHECK-NEXT: bic w8, w0, w2 183; CHECK-NEXT: and w9, w1, w2 184; CHECK-NEXT: orr w0, w9, w8 185; CHECK-NEXT: ret 186 %n0 = xor i32 %x, %y 187 %n1 = and i32 %n0, %mask 188 %r = xor i32 %x, %n1 ; swapped, %x instead of %y 189 ret i32 %r 190} 191define i32 @in_commutativity_1_1_1(i32 %x, i32 %y, i32 %mask) { 192; CHECK-LABEL: in_commutativity_1_1_1: 193; CHECK: // %bb.0: 194; CHECK-NEXT: bic w8, w0, w2 195; CHECK-NEXT: and w9, w1, w2 196; CHECK-NEXT: orr w0, w9, w8 197; CHECK-NEXT: ret 198 %n0 = xor i32 %x, %y 199 %n1 = and i32 %mask, %n0 ; swapped 200 %r = xor i32 %x, %n1 ; swapped, %x instead of %y 201 ret i32 %r 202} 203; ============================================================================ ; 204; Y is an 'and' too. 205; ============================================================================ ; 206define i32 @in_complex_y0(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) { 207; CHECK-LABEL: in_complex_y0: 208; CHECK: // %bb.0: 209; CHECK-NEXT: and w8, w1, w2 210; CHECK-NEXT: and w9, w0, w3 211; CHECK-NEXT: bic w8, w8, w3 212; CHECK-NEXT: orr w0, w9, w8 213; CHECK-NEXT: ret 214 %y = and i32 %y_hi, %y_low 215 %n0 = xor i32 %x, %y 216 %n1 = and i32 %n0, %mask 217 %r = xor i32 %n1, %y 218 ret i32 %r 219} 220define i32 @in_complex_y1(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) { 221; CHECK-LABEL: in_complex_y1: 222; CHECK: // %bb.0: 223; CHECK-NEXT: and w8, w1, w2 224; CHECK-NEXT: and w9, w0, w3 225; CHECK-NEXT: bic w8, w8, w3 226; CHECK-NEXT: orr w0, w9, w8 227; CHECK-NEXT: ret 228 %y = and i32 %y_hi, %y_low 229 %n0 = xor i32 %x, %y 230 %n1 = and i32 %n0, %mask 231 %r = xor i32 %y, %n1 232 ret i32 %r 233} 234; ============================================================================ ; 235; M is an 'xor' too. 236; ============================================================================ ; 237define i32 @in_complex_m0(i32 %x, i32 %y, i32 %m_a, i32 %m_b) { 238; CHECK-LABEL: in_complex_m0: 239; CHECK: // %bb.0: 240; CHECK-NEXT: eor w8, w2, w3 241; CHECK-NEXT: bic w9, w1, w8 242; CHECK-NEXT: and w8, w0, w8 243; CHECK-NEXT: orr w0, w8, w9 244; CHECK-NEXT: ret 245 %mask = xor i32 %m_a, %m_b 246 %n0 = xor i32 %x, %y 247 %n1 = and i32 %n0, %mask 248 %r = xor i32 %n1, %y 249 ret i32 %r 250} 251define i32 @in_complex_m1(i32 %x, i32 %y, i32 %m_a, i32 %m_b) { 252; CHECK-LABEL: in_complex_m1: 253; CHECK: // %bb.0: 254; CHECK-NEXT: eor w8, w2, w3 255; CHECK-NEXT: bic w9, w1, w8 256; CHECK-NEXT: and w8, w0, w8 257; CHECK-NEXT: orr w0, w8, w9 258; CHECK-NEXT: ret 259 %mask = xor i32 %m_a, %m_b 260 %n0 = xor i32 %x, %y 261 %n1 = and i32 %mask, %n0 262 %r = xor i32 %n1, %y 263 ret i32 %r 264} 265; ============================================================================ ; 266; Both Y and M are complex. 267; ============================================================================ ; 268define i32 @in_complex_y0_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 269; CHECK-LABEL: in_complex_y0_m0: 270; CHECK: // %bb.0: 271; CHECK-NEXT: and w8, w1, w2 272; CHECK-NEXT: eor w9, w3, w4 273; CHECK-NEXT: bic w8, w8, w9 274; CHECK-NEXT: and w9, w0, w9 275; CHECK-NEXT: orr w0, w9, w8 276; CHECK-NEXT: ret 277 %y = and i32 %y_hi, %y_low 278 %mask = xor i32 %m_a, %m_b 279 %n0 = xor i32 %x, %y 280 %n1 = and i32 %n0, %mask 281 %r = xor i32 %n1, %y 282 ret i32 %r 283} 284define i32 @in_complex_y1_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 285; CHECK-LABEL: in_complex_y1_m0: 286; CHECK: // %bb.0: 287; CHECK-NEXT: and w8, w1, w2 288; CHECK-NEXT: eor w9, w3, w4 289; CHECK-NEXT: bic w8, w8, w9 290; CHECK-NEXT: and w9, w0, w9 291; CHECK-NEXT: orr w0, w9, w8 292; CHECK-NEXT: ret 293 %y = and i32 %y_hi, %y_low 294 %mask = xor i32 %m_a, %m_b 295 %n0 = xor i32 %x, %y 296 %n1 = and i32 %n0, %mask 297 %r = xor i32 %y, %n1 298 ret i32 %r 299} 300define i32 @in_complex_y0_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 301; CHECK-LABEL: in_complex_y0_m1: 302; CHECK: // %bb.0: 303; CHECK-NEXT: and w8, w1, w2 304; CHECK-NEXT: eor w9, w3, w4 305; CHECK-NEXT: bic w8, w8, w9 306; CHECK-NEXT: and w9, w0, w9 307; CHECK-NEXT: orr w0, w9, w8 308; CHECK-NEXT: ret 309 %y = and i32 %y_hi, %y_low 310 %mask = xor i32 %m_a, %m_b 311 %n0 = xor i32 %x, %y 312 %n1 = and i32 %mask, %n0 313 %r = xor i32 %n1, %y 314 ret i32 %r 315} 316define i32 @in_complex_y1_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { 317; CHECK-LABEL: in_complex_y1_m1: 318; CHECK: // %bb.0: 319; CHECK-NEXT: and w8, w1, w2 320; CHECK-NEXT: eor w9, w3, w4 321; CHECK-NEXT: bic w8, w8, w9 322; CHECK-NEXT: and w9, w0, w9 323; CHECK-NEXT: orr w0, w9, w8 324; CHECK-NEXT: ret 325 %y = and i32 %y_hi, %y_low 326 %mask = xor i32 %m_a, %m_b 327 %n0 = xor i32 %x, %y 328 %n1 = and i32 %mask, %n0 329 %r = xor i32 %y, %n1 330 ret i32 %r 331} 332; ============================================================================ ; 333; Various cases with %x and/or %y being a constant 334; ============================================================================ ; 335define i32 @out_constant_varx_mone(i32 %x, i32 %y, i32 %mask) { 336; CHECK-LABEL: out_constant_varx_mone: 337; CHECK: // %bb.0: 338; CHECK-NEXT: and w8, w2, w0 339; CHECK-NEXT: orn w0, w8, w2 340; CHECK-NEXT: ret 341 %notmask = xor i32 %mask, -1 342 %mx = and i32 %mask, %x 343 %my = and i32 %notmask, -1 344 %r = or i32 %mx, %my 345 ret i32 %r 346} 347define i32 @in_constant_varx_mone(i32 %x, i32 %y, i32 %mask) { 348; CHECK-LABEL: in_constant_varx_mone: 349; CHECK: // %bb.0: 350; CHECK-NEXT: bic w8, w2, w0 351; CHECK-NEXT: mvn w0, w8 352; CHECK-NEXT: ret 353 %n0 = xor i32 %x, -1 ; %x 354 %n1 = and i32 %n0, %mask 355 %r = xor i32 %n1, -1 356 ret i32 %r 357} 358; This is not a canonical form. Testing for completeness only. 359define i32 @out_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) { 360; CHECK-LABEL: out_constant_varx_mone_invmask: 361; CHECK: // %bb.0: 362; CHECK-NEXT: bic w8, w0, w2 363; CHECK-NEXT: orr w0, w8, w2 364; CHECK-NEXT: ret 365 %notmask = xor i32 %mask, -1 366 %mx = and i32 %notmask, %x 367 %my = and i32 %mask, -1 368 %r = or i32 %mx, %my 369 ret i32 %r 370} 371; This is not a canonical form. Testing for completeness only. 372define i32 @in_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) { 373; CHECK-LABEL: in_constant_varx_mone_invmask: 374; CHECK: // %bb.0: 375; CHECK-NEXT: mvn w8, w0 376; CHECK-NEXT: bic w8, w8, w2 377; CHECK-NEXT: mvn w0, w8 378; CHECK-NEXT: ret 379 %notmask = xor i32 %mask, -1 380 %n0 = xor i32 %x, -1 ; %x 381 %n1 = and i32 %n0, %notmask 382 %r = xor i32 %n1, -1 383 ret i32 %r 384} 385define i32 @out_constant_varx_42(i32 %x, i32 %y, i32 %mask) { 386; CHECK-LABEL: out_constant_varx_42: 387; CHECK: // %bb.0: 388; CHECK-NEXT: mov w9, #42 389; CHECK-NEXT: and w8, w2, w0 390; CHECK-NEXT: bic w9, w9, w2 391; CHECK-NEXT: orr w0, w8, w9 392; CHECK-NEXT: ret 393 %notmask = xor i32 %mask, -1 394 %mx = and i32 %mask, %x 395 %my = and i32 %notmask, 42 396 %r = or i32 %mx, %my 397 ret i32 %r 398} 399define i32 @in_constant_varx_42(i32 %x, i32 %y, i32 %mask) { 400; CHECK-LABEL: in_constant_varx_42: 401; CHECK: // %bb.0: 402; CHECK-NEXT: mov w8, #42 403; CHECK-NEXT: bic w8, w8, w2 404; CHECK-NEXT: and w9, w0, w2 405; CHECK-NEXT: orr w0, w9, w8 406; CHECK-NEXT: ret 407 %n0 = xor i32 %x, 42 ; %x 408 %n1 = and i32 %n0, %mask 409 %r = xor i32 %n1, 42 410 ret i32 %r 411} 412; This is not a canonical form. Testing for completeness only. 413define i32 @out_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) { 414; CHECK-LABEL: out_constant_varx_42_invmask: 415; CHECK: // %bb.0: 416; CHECK-NEXT: mov w9, #42 417; CHECK-NEXT: bic w8, w0, w2 418; CHECK-NEXT: and w9, w2, w9 419; CHECK-NEXT: orr w0, w8, w9 420; CHECK-NEXT: ret 421 %notmask = xor i32 %mask, -1 422 %mx = and i32 %notmask, %x 423 %my = and i32 %mask, 42 424 %r = or i32 %mx, %my 425 ret i32 %r 426} 427; This is not a canonical form. Testing for completeness only. 428define i32 @in_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) { 429; CHECK-LABEL: in_constant_varx_42_invmask: 430; CHECK: // %bb.0: 431; CHECK-NEXT: mov w8, #42 432; CHECK-NEXT: and w8, w2, w8 433; CHECK-NEXT: bic w9, w0, w2 434; CHECK-NEXT: orr w0, w9, w8 435; CHECK-NEXT: ret 436 %notmask = xor i32 %mask, -1 437 %n0 = xor i32 %x, 42 ; %x 438 %n1 = and i32 %n0, %notmask 439 %r = xor i32 %n1, 42 440 ret i32 %r 441} 442define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) { 443; CHECK-LABEL: out_constant_mone_vary: 444; CHECK: // %bb.0: 445; CHECK-NEXT: bic w8, w1, w2 446; CHECK-NEXT: orr w0, w2, w8 447; CHECK-NEXT: ret 448 %notmask = xor i32 %mask, -1 449 %mx = and i32 %mask, -1 450 %my = and i32 %notmask, %y 451 %r = or i32 %mx, %my 452 ret i32 %r 453} 454define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) { 455; CHECK-LABEL: in_constant_mone_vary: 456; CHECK: // %bb.0: 457; CHECK-NEXT: bic w8, w2, w1 458; CHECK-NEXT: eor w0, w8, w1 459; CHECK-NEXT: ret 460 %n0 = xor i32 -1, %y ; %x 461 %n1 = and i32 %n0, %mask 462 %r = xor i32 %n1, %y 463 ret i32 %r 464} 465; This is not a canonical form. Testing for completeness only. 466define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { 467; CHECK-LABEL: out_constant_mone_vary_invmask: 468; CHECK: // %bb.0: 469; CHECK-NEXT: and w8, w2, w1 470; CHECK-NEXT: orn w0, w8, w2 471; CHECK-NEXT: ret 472 %notmask = xor i32 %mask, -1 473 %mx = and i32 %notmask, -1 474 %my = and i32 %mask, %y 475 %r = or i32 %mx, %my 476 ret i32 %r 477} 478; This is not a canonical form. Testing for completeness only. 479define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { 480; CHECK-LABEL: in_constant_mone_vary_invmask: 481; CHECK: // %bb.0: 482; CHECK-NEXT: mvn w8, w1 483; CHECK-NEXT: bic w8, w8, w2 484; CHECK-NEXT: eor w0, w8, w1 485; CHECK-NEXT: ret 486 %notmask = xor i32 %mask, -1 487 %n0 = xor i32 -1, %y ; %x 488 %n1 = and i32 %n0, %notmask 489 %r = xor i32 %n1, %y 490 ret i32 %r 491} 492define i32 @out_constant_42_vary(i32 %x, i32 %y, i32 %mask) { 493; CHECK-LABEL: out_constant_42_vary: 494; CHECK: // %bb.0: 495; CHECK-NEXT: mov w8, #42 496; CHECK-NEXT: and w8, w2, w8 497; CHECK-NEXT: bic w9, w1, w2 498; CHECK-NEXT: orr w0, w8, w9 499; CHECK-NEXT: ret 500 %notmask = xor i32 %mask, -1 501 %mx = and i32 %mask, 42 502 %my = and i32 %notmask, %y 503 %r = or i32 %mx, %my 504 ret i32 %r 505} 506define i32 @in_constant_42_vary(i32 %x, i32 %y, i32 %mask) { 507; CHECK-LABEL: in_constant_42_vary: 508; CHECK: // %bb.0: 509; CHECK-NEXT: mov w9, #42 510; CHECK-NEXT: bic w8, w1, w2 511; CHECK-NEXT: and w9, w2, w9 512; CHECK-NEXT: orr w0, w9, w8 513; CHECK-NEXT: ret 514 %n0 = xor i32 42, %y ; %x 515 %n1 = and i32 %n0, %mask 516 %r = xor i32 %n1, %y 517 ret i32 %r 518} 519; This is not a canonical form. Testing for completeness only. 520define i32 @out_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) { 521; CHECK-LABEL: out_constant_42_vary_invmask: 522; CHECK: // %bb.0: 523; CHECK-NEXT: mov w8, #42 524; CHECK-NEXT: bic w8, w8, w2 525; CHECK-NEXT: and w9, w2, w1 526; CHECK-NEXT: orr w0, w8, w9 527; CHECK-NEXT: ret 528 %notmask = xor i32 %mask, -1 529 %mx = and i32 %notmask, 42 530 %my = and i32 %mask, %y 531 %r = or i32 %mx, %my 532 ret i32 %r 533} 534; This is not a canonical form. Testing for completeness only. 535define i32 @in_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) { 536; CHECK-LABEL: in_constant_42_vary_invmask: 537; CHECK: // %bb.0: 538; CHECK-NEXT: mov w9, #42 539; CHECK-NEXT: and w8, w1, w2 540; CHECK-NEXT: bic w9, w9, w2 541; CHECK-NEXT: orr w0, w9, w8 542; CHECK-NEXT: ret 543 %notmask = xor i32 %mask, -1 544 %n0 = xor i32 42, %y ; %x 545 %n1 = and i32 %n0, %notmask 546 %r = xor i32 %n1, %y 547 ret i32 %r 548} 549; ============================================================================ ; 550; Negative tests. Should not be folded. 551; ============================================================================ ; 552; Multi-use tests. 553declare void @use32(i32) nounwind 554define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { 555; CHECK-LABEL: in_multiuse_A: 556; CHECK: // %bb.0: 557; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill 558; CHECK-NEXT: eor w8, w0, w1 559; CHECK-NEXT: and w20, w8, w3 560; CHECK-NEXT: mov w0, w20 561; CHECK-NEXT: stp x19, x30, [sp, #16] // 8-byte Folded Spill 562; CHECK-NEXT: mov w19, w1 563; CHECK-NEXT: bl use32 564; CHECK-NEXT: eor w0, w20, w19 565; CHECK-NEXT: ldp x19, x30, [sp, #16] // 8-byte Folded Reload 566; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload 567; CHECK-NEXT: ret 568 %n0 = xor i32 %x, %y 569 %n1 = and i32 %n0, %mask 570 call void @use32(i32 %n1) 571 %r = xor i32 %n1, %y 572 ret i32 %r 573} 574define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { 575; CHECK-LABEL: in_multiuse_B: 576; CHECK: // %bb.0: 577; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill 578; CHECK-NEXT: eor w0, w0, w1 579; CHECK-NEXT: stp x19, x30, [sp, #16] // 8-byte Folded Spill 580; CHECK-NEXT: mov w19, w1 581; CHECK-NEXT: and w20, w0, w3 582; CHECK-NEXT: bl use32 583; CHECK-NEXT: eor w0, w20, w19 584; CHECK-NEXT: ldp x19, x30, [sp, #16] // 8-byte Folded Reload 585; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload 586; CHECK-NEXT: ret 587 %n0 = xor i32 %x, %y 588 %n1 = and i32 %n0, %mask 589 call void @use32(i32 %n0) 590 %r = xor i32 %n1, %y 591 ret i32 %r 592} 593; Various bad variants 594define i32 @n0_badmask(i32 %x, i32 %y, i32 %mask, i32 %mask2) { 595; CHECK-LABEL: n0_badmask: 596; CHECK: // %bb.0: 597; CHECK-NEXT: and w8, w0, w2 598; CHECK-NEXT: bic w9, w1, w3 599; CHECK-NEXT: orr w0, w8, w9 600; CHECK-NEXT: ret 601 %mx = and i32 %x, %mask 602 %notmask = xor i32 %mask2, -1 ; %mask2 instead of %mask 603 %my = and i32 %y, %notmask 604 %r = or i32 %mx, %my 605 ret i32 %r 606} 607define i32 @n0_badxor(i32 %x, i32 %y, i32 %mask) { 608; CHECK-LABEL: n0_badxor: 609; CHECK: // %bb.0: 610; CHECK-NEXT: eor w9, w2, #0x1 611; CHECK-NEXT: and w8, w0, w2 612; CHECK-NEXT: and w9, w1, w9 613; CHECK-NEXT: orr w0, w8, w9 614; CHECK-NEXT: ret 615 %mx = and i32 %x, %mask 616 %notmask = xor i32 %mask, 1 ; instead of -1 617 %my = and i32 %y, %notmask 618 %r = or i32 %mx, %my 619 ret i32 %r 620} 621define i32 @n1_thirdvar(i32 %x, i32 %y, i32 %z, i32 %mask) { 622; CHECK-LABEL: n1_thirdvar: 623; CHECK: // %bb.0: 624; CHECK-NEXT: eor w8, w0, w1 625; CHECK-NEXT: and w8, w8, w3 626; CHECK-NEXT: eor w0, w8, w2 627; CHECK-NEXT: ret 628 %n0 = xor i32 %x, %y 629 %n1 = and i32 %n0, %mask 630 %r = xor i32 %n1, %z ; instead of %y 631 ret i32 %r 632} 633