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: bic w8, w1, w2 69; CHECK-NEXT: and w9, w0, w2 70; CHECK-NEXT: orr w0, w9, w8 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: bic w8, w1, w2 82; CHECK-NEXT: and w9, w0, w2 83; CHECK-NEXT: orr w0, w9, w8 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: orr w0, w0, w2 363; CHECK-NEXT: ret 364 %notmask = xor i32 %mask, -1 365 %mx = and i32 %notmask, %x 366 %my = and i32 %mask, -1 367 %r = or i32 %mx, %my 368 ret i32 %r 369} 370; This is not a canonical form. Testing for completeness only. 371define i32 @in_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) { 372; CHECK-LABEL: in_constant_varx_mone_invmask: 373; CHECK: // %bb.0: 374; CHECK-NEXT: mvn w8, w0 375; CHECK-NEXT: bic w8, w8, w2 376; CHECK-NEXT: mvn w0, w8 377; CHECK-NEXT: ret 378 %notmask = xor i32 %mask, -1 379 %n0 = xor i32 %x, -1 ; %x 380 %n1 = and i32 %n0, %notmask 381 %r = xor i32 %n1, -1 382 ret i32 %r 383} 384define i32 @out_constant_varx_42(i32 %x, i32 %y, i32 %mask) { 385; CHECK-LABEL: out_constant_varx_42: 386; CHECK: // %bb.0: 387; CHECK-NEXT: mov w9, #42 388; CHECK-NEXT: and w8, w2, w0 389; CHECK-NEXT: bic w9, w9, w2 390; CHECK-NEXT: orr w0, w8, w9 391; CHECK-NEXT: ret 392 %notmask = xor i32 %mask, -1 393 %mx = and i32 %mask, %x 394 %my = and i32 %notmask, 42 395 %r = or i32 %mx, %my 396 ret i32 %r 397} 398define i32 @in_constant_varx_42(i32 %x, i32 %y, i32 %mask) { 399; CHECK-LABEL: in_constant_varx_42: 400; CHECK: // %bb.0: 401; CHECK-NEXT: mov w8, #42 402; CHECK-NEXT: bic w8, w8, w2 403; CHECK-NEXT: and w9, w0, w2 404; CHECK-NEXT: orr w0, w9, w8 405; CHECK-NEXT: ret 406 %n0 = xor i32 %x, 42 ; %x 407 %n1 = and i32 %n0, %mask 408 %r = xor i32 %n1, 42 409 ret i32 %r 410} 411; This is not a canonical form. Testing for completeness only. 412define i32 @out_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) { 413; CHECK-LABEL: out_constant_varx_42_invmask: 414; CHECK: // %bb.0: 415; CHECK-NEXT: mov w9, #42 416; CHECK-NEXT: bic w8, w0, w2 417; CHECK-NEXT: and w9, w2, w9 418; CHECK-NEXT: orr w0, w8, w9 419; CHECK-NEXT: ret 420 %notmask = xor i32 %mask, -1 421 %mx = and i32 %notmask, %x 422 %my = and i32 %mask, 42 423 %r = or i32 %mx, %my 424 ret i32 %r 425} 426; This is not a canonical form. Testing for completeness only. 427define i32 @in_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) { 428; CHECK-LABEL: in_constant_varx_42_invmask: 429; CHECK: // %bb.0: 430; CHECK-NEXT: mov w8, #42 431; CHECK-NEXT: and w8, w2, w8 432; CHECK-NEXT: bic w9, w0, w2 433; CHECK-NEXT: orr w0, w9, w8 434; CHECK-NEXT: ret 435 %notmask = xor i32 %mask, -1 436 %n0 = xor i32 %x, 42 ; %x 437 %n1 = and i32 %n0, %notmask 438 %r = xor i32 %n1, 42 439 ret i32 %r 440} 441define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) { 442; CHECK-LABEL: out_constant_mone_vary: 443; CHECK: // %bb.0: 444; CHECK-NEXT: orr w0, w1, w2 445; CHECK-NEXT: ret 446 %notmask = xor i32 %mask, -1 447 %mx = and i32 %mask, -1 448 %my = and i32 %notmask, %y 449 %r = or i32 %mx, %my 450 ret i32 %r 451} 452define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) { 453; CHECK-LABEL: in_constant_mone_vary: 454; CHECK: // %bb.0: 455; CHECK-NEXT: bic w8, w2, w1 456; CHECK-NEXT: eor w0, w8, w1 457; CHECK-NEXT: ret 458 %n0 = xor i32 -1, %y ; %x 459 %n1 = and i32 %n0, %mask 460 %r = xor i32 %n1, %y 461 ret i32 %r 462} 463; This is not a canonical form. Testing for completeness only. 464define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { 465; CHECK-LABEL: out_constant_mone_vary_invmask: 466; CHECK: // %bb.0: 467; CHECK-NEXT: and w8, w2, w1 468; CHECK-NEXT: orn w0, w8, w2 469; CHECK-NEXT: ret 470 %notmask = xor i32 %mask, -1 471 %mx = and i32 %notmask, -1 472 %my = and i32 %mask, %y 473 %r = or i32 %mx, %my 474 ret i32 %r 475} 476; This is not a canonical form. Testing for completeness only. 477define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { 478; CHECK-LABEL: in_constant_mone_vary_invmask: 479; CHECK: // %bb.0: 480; CHECK-NEXT: mvn w8, w1 481; CHECK-NEXT: bic w8, w8, w2 482; CHECK-NEXT: eor w0, w8, w1 483; CHECK-NEXT: ret 484 %notmask = xor i32 %mask, -1 485 %n0 = xor i32 -1, %y ; %x 486 %n1 = and i32 %n0, %notmask 487 %r = xor i32 %n1, %y 488 ret i32 %r 489} 490define i32 @out_constant_42_vary(i32 %x, i32 %y, i32 %mask) { 491; CHECK-LABEL: out_constant_42_vary: 492; CHECK: // %bb.0: 493; CHECK-NEXT: mov w8, #42 494; CHECK-NEXT: and w8, w2, w8 495; CHECK-NEXT: bic w9, w1, w2 496; CHECK-NEXT: orr w0, w8, w9 497; CHECK-NEXT: ret 498 %notmask = xor i32 %mask, -1 499 %mx = and i32 %mask, 42 500 %my = and i32 %notmask, %y 501 %r = or i32 %mx, %my 502 ret i32 %r 503} 504define i32 @in_constant_42_vary(i32 %x, i32 %y, i32 %mask) { 505; CHECK-LABEL: in_constant_42_vary: 506; CHECK: // %bb.0: 507; CHECK-NEXT: mov w9, #42 508; CHECK-NEXT: bic w8, w1, w2 509; CHECK-NEXT: and w9, w2, w9 510; CHECK-NEXT: orr w0, w9, w8 511; CHECK-NEXT: ret 512 %n0 = xor i32 42, %y ; %x 513 %n1 = and i32 %n0, %mask 514 %r = xor i32 %n1, %y 515 ret i32 %r 516} 517; This is not a canonical form. Testing for completeness only. 518define i32 @out_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) { 519; CHECK-LABEL: out_constant_42_vary_invmask: 520; CHECK: // %bb.0: 521; CHECK-NEXT: mov w8, #42 522; CHECK-NEXT: bic w8, w8, w2 523; CHECK-NEXT: and w9, w2, w1 524; CHECK-NEXT: orr w0, w8, w9 525; CHECK-NEXT: ret 526 %notmask = xor i32 %mask, -1 527 %mx = and i32 %notmask, 42 528 %my = and i32 %mask, %y 529 %r = or i32 %mx, %my 530 ret i32 %r 531} 532; This is not a canonical form. Testing for completeness only. 533define i32 @in_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) { 534; CHECK-LABEL: in_constant_42_vary_invmask: 535; CHECK: // %bb.0: 536; CHECK-NEXT: mov w9, #42 537; CHECK-NEXT: and w8, w1, w2 538; CHECK-NEXT: bic w9, w9, w2 539; CHECK-NEXT: orr w0, w9, w8 540; CHECK-NEXT: ret 541 %notmask = xor i32 %mask, -1 542 %n0 = xor i32 42, %y ; %x 543 %n1 = and i32 %n0, %notmask 544 %r = xor i32 %n1, %y 545 ret i32 %r 546} 547; ============================================================================ ; 548; Negative tests. Should not be folded. 549; ============================================================================ ; 550; Multi-use tests. 551declare void @use32(i32) nounwind 552define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { 553; CHECK-LABEL: in_multiuse_A: 554; CHECK: // %bb.0: 555; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill 556; CHECK-NEXT: eor w8, w0, w1 557; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill 558; CHECK-NEXT: and w20, w8, w3 559; CHECK-NEXT: mov w0, w20 560; CHECK-NEXT: mov w19, w1 561; CHECK-NEXT: bl use32 562; CHECK-NEXT: eor w0, w20, w19 563; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload 564; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload 565; CHECK-NEXT: ret 566 %n0 = xor i32 %x, %y 567 %n1 = and i32 %n0, %mask 568 call void @use32(i32 %n1) 569 %r = xor i32 %n1, %y 570 ret i32 %r 571} 572define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { 573; CHECK-LABEL: in_multiuse_B: 574; CHECK: // %bb.0: 575; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill 576; CHECK-NEXT: eor w0, w0, w1 577; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill 578; CHECK-NEXT: mov w19, w1 579; CHECK-NEXT: and w20, w0, w3 580; CHECK-NEXT: bl use32 581; CHECK-NEXT: eor w0, w20, w19 582; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload 583; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload 584; CHECK-NEXT: ret 585 %n0 = xor i32 %x, %y 586 %n1 = and i32 %n0, %mask 587 call void @use32(i32 %n0) 588 %r = xor i32 %n1, %y 589 ret i32 %r 590} 591; Various bad variants 592define i32 @n0_badmask(i32 %x, i32 %y, i32 %mask, i32 %mask2) { 593; CHECK-LABEL: n0_badmask: 594; CHECK: // %bb.0: 595; CHECK-NEXT: and w8, w0, w2 596; CHECK-NEXT: bic w9, w1, w3 597; CHECK-NEXT: orr w0, w8, w9 598; CHECK-NEXT: ret 599 %mx = and i32 %x, %mask 600 %notmask = xor i32 %mask2, -1 ; %mask2 instead of %mask 601 %my = and i32 %y, %notmask 602 %r = or i32 %mx, %my 603 ret i32 %r 604} 605define i32 @n0_badxor(i32 %x, i32 %y, i32 %mask) { 606; CHECK-LABEL: n0_badxor: 607; CHECK: // %bb.0: 608; CHECK-NEXT: eor w9, w2, #0x1 609; CHECK-NEXT: and w8, w0, w2 610; CHECK-NEXT: and w9, w1, w9 611; CHECK-NEXT: orr w0, w8, w9 612; CHECK-NEXT: ret 613 %mx = and i32 %x, %mask 614 %notmask = xor i32 %mask, 1 ; instead of -1 615 %my = and i32 %y, %notmask 616 %r = or i32 %mx, %my 617 ret i32 %r 618} 619define i32 @n1_thirdvar(i32 %x, i32 %y, i32 %z, i32 %mask) { 620; CHECK-LABEL: n1_thirdvar: 621; CHECK: // %bb.0: 622; CHECK-NEXT: eor w8, w0, w1 623; CHECK-NEXT: and w8, w8, w3 624; CHECK-NEXT: eor w0, w8, w2 625; CHECK-NEXT: ret 626 %n0 = xor i32 %x, %y 627 %n1 = and i32 %n0, %mask 628 %r = xor i32 %n1, %z ; instead of %y 629 ret i32 %r 630} 631