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: eor w8, w3, w4 272; CHECK-NEXT: and w9, w1, w2 273; CHECK-NEXT: bic w9, w9, w8 274; CHECK-NEXT: and w8, w0, w8 275; CHECK-NEXT: orr w0, w8, w9 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: eor w8, w3, w4 288; CHECK-NEXT: and w9, w1, w2 289; CHECK-NEXT: bic w9, w9, w8 290; CHECK-NEXT: and w8, w0, w8 291; CHECK-NEXT: orr w0, w8, w9 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: eor w8, w3, w4 304; CHECK-NEXT: and w9, w1, w2 305; CHECK-NEXT: bic w9, w9, w8 306; CHECK-NEXT: and w8, w0, w8 307; CHECK-NEXT: orr w0, w8, w9 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: eor w8, w3, w4 320; CHECK-NEXT: and w9, w1, w2 321; CHECK-NEXT: bic w9, w9, w8 322; CHECK-NEXT: and w8, w0, w8 323; CHECK-NEXT: orr w0, w8, w9 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 w8, #42 // =0x2a 388; CHECK-NEXT: and w9, w2, w0 389; CHECK-NEXT: bic w8, w8, w2 390; CHECK-NEXT: orr w0, w9, w8 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 // =0x2a 402; CHECK-NEXT: and w9, w0, w2 403; CHECK-NEXT: bic w8, w8, 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 w8, #42 // =0x2a 416; CHECK-NEXT: bic w9, w0, w2 417; CHECK-NEXT: and w8, w2, w8 418; CHECK-NEXT: orr w0, w9, w8 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 // =0x2a 431; CHECK-NEXT: bic w9, w0, w2 432; CHECK-NEXT: and w8, w2, w8 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: orr w0, w2, w1 456; CHECK-NEXT: ret 457 %n0 = xor i32 -1, %y ; %x 458 %n1 = and i32 %n0, %mask 459 %r = xor i32 %n1, %y 460 ret i32 %r 461} 462; This is not a canonical form. Testing for completeness only. 463define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { 464; CHECK-LABEL: out_constant_mone_vary_invmask: 465; CHECK: // %bb.0: 466; CHECK-NEXT: and w8, w2, w1 467; CHECK-NEXT: orn w0, w8, w2 468; CHECK-NEXT: ret 469 %notmask = xor i32 %mask, -1 470 %mx = and i32 %notmask, -1 471 %my = and i32 %mask, %y 472 %r = or i32 %mx, %my 473 ret i32 %r 474} 475; This is not a canonical form. Testing for completeness only. 476define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { 477; CHECK-LABEL: in_constant_mone_vary_invmask: 478; CHECK: // %bb.0: 479; CHECK-NEXT: orn w0, w1, w2 480; CHECK-NEXT: ret 481 %notmask = xor i32 %mask, -1 482 %n0 = xor i32 -1, %y ; %x 483 %n1 = and i32 %n0, %notmask 484 %r = xor i32 %n1, %y 485 ret i32 %r 486} 487define i32 @out_constant_42_vary(i32 %x, i32 %y, i32 %mask) { 488; CHECK-LABEL: out_constant_42_vary: 489; CHECK: // %bb.0: 490; CHECK-NEXT: mov w8, #42 // =0x2a 491; CHECK-NEXT: bic w9, w1, w2 492; CHECK-NEXT: and w8, w2, w8 493; CHECK-NEXT: orr w0, w8, w9 494; CHECK-NEXT: ret 495 %notmask = xor i32 %mask, -1 496 %mx = and i32 %mask, 42 497 %my = and i32 %notmask, %y 498 %r = or i32 %mx, %my 499 ret i32 %r 500} 501define i32 @in_constant_42_vary(i32 %x, i32 %y, i32 %mask) { 502; CHECK-LABEL: in_constant_42_vary: 503; CHECK: // %bb.0: 504; CHECK-NEXT: mov w8, #42 // =0x2a 505; CHECK-NEXT: bic w9, w1, w2 506; CHECK-NEXT: and w8, w2, w8 507; CHECK-NEXT: orr w0, w8, w9 508; CHECK-NEXT: ret 509 %n0 = xor i32 42, %y ; %x 510 %n1 = and i32 %n0, %mask 511 %r = xor i32 %n1, %y 512 ret i32 %r 513} 514; This is not a canonical form. Testing for completeness only. 515define i32 @out_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) { 516; CHECK-LABEL: out_constant_42_vary_invmask: 517; CHECK: // %bb.0: 518; CHECK-NEXT: mov w8, #42 // =0x2a 519; CHECK-NEXT: and w9, w2, w1 520; CHECK-NEXT: bic w8, w8, w2 521; CHECK-NEXT: orr w0, w8, w9 522; CHECK-NEXT: ret 523 %notmask = xor i32 %mask, -1 524 %mx = and i32 %notmask, 42 525 %my = and i32 %mask, %y 526 %r = or i32 %mx, %my 527 ret i32 %r 528} 529; This is not a canonical form. Testing for completeness only. 530define i32 @in_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) { 531; CHECK-LABEL: in_constant_42_vary_invmask: 532; CHECK: // %bb.0: 533; CHECK-NEXT: mov w8, #42 // =0x2a 534; CHECK-NEXT: and w9, w1, w2 535; CHECK-NEXT: bic w8, w8, w2 536; CHECK-NEXT: orr w0, w8, w9 537; CHECK-NEXT: ret 538 %notmask = xor i32 %mask, -1 539 %n0 = xor i32 42, %y ; %x 540 %n1 = and i32 %n0, %notmask 541 %r = xor i32 %n1, %y 542 ret i32 %r 543} 544; ============================================================================ ; 545; Negative tests. Should not be folded. 546; ============================================================================ ; 547; Multi-use tests. 548declare void @use32(i32) nounwind 549define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { 550; CHECK-LABEL: in_multiuse_A: 551; CHECK: // %bb.0: 552; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill 553; CHECK-NEXT: eor w8, w0, w1 554; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill 555; CHECK-NEXT: mov w19, w1 556; CHECK-NEXT: and w20, w8, w3 557; CHECK-NEXT: mov w0, w20 558; CHECK-NEXT: bl use32 559; CHECK-NEXT: eor w0, w20, w19 560; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload 561; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload 562; CHECK-NEXT: ret 563 %n0 = xor i32 %x, %y 564 %n1 = and i32 %n0, %mask 565 call void @use32(i32 %n1) 566 %r = xor i32 %n1, %y 567 ret i32 %r 568} 569define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { 570; CHECK-LABEL: in_multiuse_B: 571; CHECK: // %bb.0: 572; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill 573; CHECK-NEXT: eor w0, w0, w1 574; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill 575; CHECK-NEXT: mov w19, w1 576; CHECK-NEXT: and w20, w0, w3 577; CHECK-NEXT: bl use32 578; CHECK-NEXT: eor w0, w20, w19 579; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload 580; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload 581; CHECK-NEXT: ret 582 %n0 = xor i32 %x, %y 583 %n1 = and i32 %n0, %mask 584 call void @use32(i32 %n0) 585 %r = xor i32 %n1, %y 586 ret i32 %r 587} 588; Various bad variants 589define i32 @n0_badmask(i32 %x, i32 %y, i32 %mask, i32 %mask2) { 590; CHECK-LABEL: n0_badmask: 591; CHECK: // %bb.0: 592; CHECK-NEXT: bic w8, w1, w3 593; CHECK-NEXT: and w9, w0, w2 594; CHECK-NEXT: orr w0, w9, w8 595; CHECK-NEXT: ret 596 %mx = and i32 %x, %mask 597 %notmask = xor i32 %mask2, -1 ; %mask2 instead of %mask 598 %my = and i32 %y, %notmask 599 %r = or i32 %mx, %my 600 ret i32 %r 601} 602define i32 @n0_badxor(i32 %x, i32 %y, i32 %mask) { 603; CHECK-LABEL: n0_badxor: 604; CHECK: // %bb.0: 605; CHECK-NEXT: eor w8, w2, #0x1 606; CHECK-NEXT: and w9, w0, w2 607; CHECK-NEXT: and w8, w1, w8 608; CHECK-NEXT: orr w0, w9, w8 609; CHECK-NEXT: ret 610 %mx = and i32 %x, %mask 611 %notmask = xor i32 %mask, 1 ; instead of -1 612 %my = and i32 %y, %notmask 613 %r = or i32 %mx, %my 614 ret i32 %r 615} 616define i32 @n1_thirdvar(i32 %x, i32 %y, i32 %z, i32 %mask) { 617; CHECK-LABEL: n1_thirdvar: 618; CHECK: // %bb.0: 619; CHECK-NEXT: eor w8, w0, w1 620; CHECK-NEXT: and w8, w8, w3 621; CHECK-NEXT: eor w0, w8, w2 622; CHECK-NEXT: ret 623 %n0 = xor i32 %x, %y 624 %n1 = and i32 %n0, %mask 625 %r = xor i32 %n1, %z ; instead of %y 626 ret i32 %r 627} 628