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