1029 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 < %s \3; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-I,RV32,RV32I4; RUN: llc -mtriple=riscv64 < %s \5; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-I,RV64,RV64I6; RUN: llc -mtriple=riscv32 -mattr=+zbb < %s \7; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-ZBB,RV32,RV32ZBB8; RUN: llc -mtriple=riscv64 -mattr=+zbb < %s \9; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-ZBB,RV64,RV64ZBB10 11 12define i8 @out8(i8 %x, i8 %y, i8 %mask) {13; CHECK-I-LABEL: out8:14; CHECK-I: # %bb.0:15; CHECK-I-NEXT: xor a0, a0, a116; CHECK-I-NEXT: and a0, a0, a217; CHECK-I-NEXT: xor a0, a0, a118; CHECK-I-NEXT: ret19;20; CHECK-ZBB-LABEL: out8:21; CHECK-ZBB: # %bb.0:22; CHECK-ZBB-NEXT: and a0, a0, a223; CHECK-ZBB-NEXT: andn a1, a1, a224; CHECK-ZBB-NEXT: or a0, a0, a125; CHECK-ZBB-NEXT: ret26 %mx = and i8 %x, %mask27 %notmask = xor i8 %mask, -128 %my = and i8 %y, %notmask29 %r = or i8 %mx, %my30 ret i8 %r31}32 33define i16 @out16(i16 %x, i16 %y, i16 %mask) {34; CHECK-I-LABEL: out16:35; CHECK-I: # %bb.0:36; CHECK-I-NEXT: xor a0, a0, a137; CHECK-I-NEXT: and a0, a0, a238; CHECK-I-NEXT: xor a0, a0, a139; CHECK-I-NEXT: ret40;41; CHECK-ZBB-LABEL: out16:42; CHECK-ZBB: # %bb.0:43; CHECK-ZBB-NEXT: and a0, a0, a244; CHECK-ZBB-NEXT: andn a1, a1, a245; CHECK-ZBB-NEXT: or a0, a0, a146; CHECK-ZBB-NEXT: ret47 %mx = and i16 %x, %mask48 %notmask = xor i16 %mask, -149 %my = and i16 %y, %notmask50 %r = or i16 %mx, %my51 ret i16 %r52}53 54define i32 @out32(i32 %x, i32 %y, i32 %mask) {55; CHECK-I-LABEL: out32:56; CHECK-I: # %bb.0:57; CHECK-I-NEXT: xor a0, a0, a158; CHECK-I-NEXT: and a0, a0, a259; CHECK-I-NEXT: xor a0, a0, a160; CHECK-I-NEXT: ret61;62; CHECK-ZBB-LABEL: out32:63; CHECK-ZBB: # %bb.0:64; CHECK-ZBB-NEXT: and a0, a0, a265; CHECK-ZBB-NEXT: andn a1, a1, a266; CHECK-ZBB-NEXT: or a0, a0, a167; CHECK-ZBB-NEXT: ret68 %mx = and i32 %x, %mask69 %notmask = xor i32 %mask, -170 %my = and i32 %y, %notmask71 %r = or i32 %mx, %my72 ret i32 %r73}74 75define i64 @out64(i64 %x, i64 %y, i64 %mask) {76; RV32I-LABEL: out64:77; RV32I: # %bb.0:78; RV32I-NEXT: xor a0, a0, a279; RV32I-NEXT: xor a1, a1, a380; RV32I-NEXT: and a0, a0, a481; RV32I-NEXT: and a1, a1, a582; RV32I-NEXT: xor a0, a0, a283; RV32I-NEXT: xor a1, a1, a384; RV32I-NEXT: ret85;86; RV64I-LABEL: out64:87; RV64I: # %bb.0:88; RV64I-NEXT: xor a0, a0, a189; RV64I-NEXT: and a0, a0, a290; RV64I-NEXT: xor a0, a0, a191; RV64I-NEXT: ret92;93; RV32ZBB-LABEL: out64:94; RV32ZBB: # %bb.0:95; RV32ZBB-NEXT: and a1, a1, a596; RV32ZBB-NEXT: and a0, a0, a497; RV32ZBB-NEXT: andn a3, a3, a598; RV32ZBB-NEXT: andn a2, a2, a499; RV32ZBB-NEXT: or a0, a0, a2100; RV32ZBB-NEXT: or a1, a1, a3101; RV32ZBB-NEXT: ret102;103; RV64ZBB-LABEL: out64:104; RV64ZBB: # %bb.0:105; RV64ZBB-NEXT: and a0, a0, a2106; RV64ZBB-NEXT: andn a1, a1, a2107; RV64ZBB-NEXT: or a0, a0, a1108; RV64ZBB-NEXT: ret109 %mx = and i64 %x, %mask110 %notmask = xor i64 %mask, -1111 %my = and i64 %y, %notmask112 %r = or i64 %mx, %my113 ret i64 %r114}115 116;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;117; These tests should produce the same output as the corresponding out* test118; when the Zbb extension is enabled.119;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120 121define i8 @in8(i8 %x, i8 %y, i8 %mask) {122; CHECK-I-LABEL: in8:123; CHECK-I: # %bb.0:124; CHECK-I-NEXT: xor a0, a0, a1125; CHECK-I-NEXT: and a0, a0, a2126; CHECK-I-NEXT: xor a0, a0, a1127; CHECK-I-NEXT: ret128;129; CHECK-ZBB-LABEL: in8:130; CHECK-ZBB: # %bb.0:131; CHECK-ZBB-NEXT: andn a1, a1, a2132; CHECK-ZBB-NEXT: and a0, a0, a2133; CHECK-ZBB-NEXT: or a0, a0, a1134; CHECK-ZBB-NEXT: ret135 %n0 = xor i8 %x, %y136 %n1 = and i8 %n0, %mask137 %r = xor i8 %n1, %y138 ret i8 %r139}140 141define i16 @in16(i16 %x, i16 %y, i16 %mask) {142; CHECK-I-LABEL: in16:143; CHECK-I: # %bb.0:144; CHECK-I-NEXT: xor a0, a0, a1145; CHECK-I-NEXT: and a0, a0, a2146; CHECK-I-NEXT: xor a0, a0, a1147; CHECK-I-NEXT: ret148;149; CHECK-ZBB-LABEL: in16:150; CHECK-ZBB: # %bb.0:151; CHECK-ZBB-NEXT: andn a1, a1, a2152; CHECK-ZBB-NEXT: and a0, a0, a2153; CHECK-ZBB-NEXT: or a0, a0, a1154; CHECK-ZBB-NEXT: ret155 %n0 = xor i16 %x, %y156 %n1 = and i16 %n0, %mask157 %r = xor i16 %n1, %y158 ret i16 %r159}160 161define i32 @in32(i32 %x, i32 %y, i32 %mask) {162; CHECK-I-LABEL: in32:163; CHECK-I: # %bb.0:164; CHECK-I-NEXT: xor a0, a0, a1165; CHECK-I-NEXT: and a0, a0, a2166; CHECK-I-NEXT: xor a0, a0, a1167; CHECK-I-NEXT: ret168;169; CHECK-ZBB-LABEL: in32:170; CHECK-ZBB: # %bb.0:171; CHECK-ZBB-NEXT: andn a1, a1, a2172; CHECK-ZBB-NEXT: and a0, a0, a2173; CHECK-ZBB-NEXT: or a0, a0, a1174; CHECK-ZBB-NEXT: ret175 %n0 = xor i32 %x, %y176 %n1 = and i32 %n0, %mask177 %r = xor i32 %n1, %y178 ret i32 %r179}180 181define i64 @in64(i64 %x, i64 %y, i64 %mask) {182; RV32I-LABEL: in64:183; RV32I: # %bb.0:184; RV32I-NEXT: xor a0, a0, a2185; RV32I-NEXT: xor a1, a1, a3186; RV32I-NEXT: and a1, a1, a5187; RV32I-NEXT: and a0, a0, a4188; RV32I-NEXT: xor a0, a0, a2189; RV32I-NEXT: xor a1, a1, a3190; RV32I-NEXT: ret191;192; RV64I-LABEL: in64:193; RV64I: # %bb.0:194; RV64I-NEXT: xor a0, a0, a1195; RV64I-NEXT: and a0, a0, a2196; RV64I-NEXT: xor a0, a0, a1197; RV64I-NEXT: ret198;199; RV32ZBB-LABEL: in64:200; RV32ZBB: # %bb.0:201; RV32ZBB-NEXT: andn a2, a2, a4202; RV32ZBB-NEXT: and a0, a0, a4203; RV32ZBB-NEXT: andn a3, a3, a5204; RV32ZBB-NEXT: and a1, a1, a5205; RV32ZBB-NEXT: or a0, a0, a2206; RV32ZBB-NEXT: or a1, a1, a3207; RV32ZBB-NEXT: ret208;209; RV64ZBB-LABEL: in64:210; RV64ZBB: # %bb.0:211; RV64ZBB-NEXT: andn a1, a1, a2212; RV64ZBB-NEXT: and a0, a0, a2213; RV64ZBB-NEXT: or a0, a0, a1214; RV64ZBB-NEXT: ret215 %n0 = xor i64 %x, %y216 %n1 = and i64 %n0, %mask217 %r = xor i64 %n1, %y218 ret i64 %r219}220 221; ============================================================================ ;222; Commutativity tests.223; ============================================================================ ;224 225define i32 @in_commutativity_0_0_1(i32 %x, i32 %y, i32 %mask) {226; CHECK-I-LABEL: in_commutativity_0_0_1:227; CHECK-I: # %bb.0:228; CHECK-I-NEXT: xor a0, a0, a1229; CHECK-I-NEXT: and a0, a2, a0230; CHECK-I-NEXT: xor a0, a0, a1231; CHECK-I-NEXT: ret232;233; CHECK-ZBB-LABEL: in_commutativity_0_0_1:234; CHECK-ZBB: # %bb.0:235; CHECK-ZBB-NEXT: andn a1, a1, a2236; CHECK-ZBB-NEXT: and a0, a0, a2237; CHECK-ZBB-NEXT: or a0, a0, a1238; CHECK-ZBB-NEXT: ret239 %n0 = xor i32 %x, %y240 %n1 = and i32 %mask, %n0 ; swapped241 %r = xor i32 %n1, %y242 ret i32 %r243}244 245define i32 @in_commutativity_0_1_0(i32 %x, i32 %y, i32 %mask) {246; CHECK-I-LABEL: in_commutativity_0_1_0:247; CHECK-I: # %bb.0:248; CHECK-I-NEXT: xor a0, a0, a1249; CHECK-I-NEXT: and a0, a0, a2250; CHECK-I-NEXT: xor a0, a1, a0251; CHECK-I-NEXT: ret252;253; CHECK-ZBB-LABEL: in_commutativity_0_1_0:254; CHECK-ZBB: # %bb.0:255; CHECK-ZBB-NEXT: andn a1, a1, a2256; CHECK-ZBB-NEXT: and a0, a0, a2257; CHECK-ZBB-NEXT: or a0, a0, a1258; CHECK-ZBB-NEXT: ret259 %n0 = xor i32 %x, %y260 %n1 = and i32 %n0, %mask261 %r = xor i32 %y, %n1 ; swapped262 ret i32 %r263}264 265define i32 @in_commutativity_0_1_1(i32 %x, i32 %y, i32 %mask) {266; CHECK-I-LABEL: in_commutativity_0_1_1:267; CHECK-I: # %bb.0:268; CHECK-I-NEXT: xor a0, a0, a1269; CHECK-I-NEXT: and a0, a2, a0270; CHECK-I-NEXT: xor a0, a1, a0271; CHECK-I-NEXT: ret272;273; CHECK-ZBB-LABEL: in_commutativity_0_1_1:274; CHECK-ZBB: # %bb.0:275; CHECK-ZBB-NEXT: andn a1, a1, a2276; CHECK-ZBB-NEXT: and a0, a0, a2277; CHECK-ZBB-NEXT: or a0, a0, a1278; CHECK-ZBB-NEXT: ret279 %n0 = xor i32 %x, %y280 %n1 = and i32 %mask, %n0 ; swapped281 %r = xor i32 %y, %n1 ; swapped282 ret i32 %r283}284 285define i32 @in_commutativity_1_0_0(i32 %x, i32 %y, i32 %mask) {286; CHECK-I-LABEL: in_commutativity_1_0_0:287; CHECK-I: # %bb.0:288; CHECK-I-NEXT: xor a1, a0, a1289; CHECK-I-NEXT: and a1, a1, a2290; CHECK-I-NEXT: xor a0, a1, a0291; CHECK-I-NEXT: ret292;293; CHECK-ZBB-LABEL: in_commutativity_1_0_0:294; CHECK-ZBB: # %bb.0:295; CHECK-ZBB-NEXT: andn a0, a0, a2296; CHECK-ZBB-NEXT: and a1, a1, a2297; CHECK-ZBB-NEXT: or a0, a1, a0298; CHECK-ZBB-NEXT: ret299 %n0 = xor i32 %x, %y300 %n1 = and i32 %n0, %mask301 %r = xor i32 %n1, %x ; %x instead of %y302 ret i32 %r303}304 305define i32 @in_commutativity_1_0_1(i32 %x, i32 %y, i32 %mask) {306; CHECK-I-LABEL: in_commutativity_1_0_1:307; CHECK-I: # %bb.0:308; CHECK-I-NEXT: xor a1, a0, a1309; CHECK-I-NEXT: and a1, a2, a1310; CHECK-I-NEXT: xor a0, a1, a0311; CHECK-I-NEXT: ret312;313; CHECK-ZBB-LABEL: in_commutativity_1_0_1:314; CHECK-ZBB: # %bb.0:315; CHECK-ZBB-NEXT: andn a0, a0, a2316; CHECK-ZBB-NEXT: and a1, a1, a2317; CHECK-ZBB-NEXT: or a0, a1, a0318; CHECK-ZBB-NEXT: ret319 %n0 = xor i32 %x, %y320 %n1 = and i32 %mask, %n0 ; swapped321 %r = xor i32 %n1, %x ; %x instead of %y322 ret i32 %r323}324 325define i32 @in_commutativity_1_1_0(i32 %x, i32 %y, i32 %mask) {326; CHECK-I-LABEL: in_commutativity_1_1_0:327; CHECK-I: # %bb.0:328; CHECK-I-NEXT: xor a1, a0, a1329; CHECK-I-NEXT: and a1, a1, a2330; CHECK-I-NEXT: xor a0, a0, a1331; CHECK-I-NEXT: ret332;333; CHECK-ZBB-LABEL: in_commutativity_1_1_0:334; CHECK-ZBB: # %bb.0:335; CHECK-ZBB-NEXT: andn a0, a0, a2336; CHECK-ZBB-NEXT: and a1, a1, a2337; CHECK-ZBB-NEXT: or a0, a1, a0338; CHECK-ZBB-NEXT: ret339 %n0 = xor i32 %x, %y340 %n1 = and i32 %n0, %mask341 %r = xor i32 %x, %n1 ; swapped, %x instead of %y342 ret i32 %r343}344 345define i32 @in_commutativity_1_1_1(i32 %x, i32 %y, i32 %mask) {346; CHECK-I-LABEL: in_commutativity_1_1_1:347; CHECK-I: # %bb.0:348; CHECK-I-NEXT: xor a1, a0, a1349; CHECK-I-NEXT: and a1, a2, a1350; CHECK-I-NEXT: xor a0, a0, a1351; CHECK-I-NEXT: ret352;353; CHECK-ZBB-LABEL: in_commutativity_1_1_1:354; CHECK-ZBB: # %bb.0:355; CHECK-ZBB-NEXT: andn a0, a0, a2356; CHECK-ZBB-NEXT: and a1, a1, a2357; CHECK-ZBB-NEXT: or a0, a1, a0358; CHECK-ZBB-NEXT: ret359 %n0 = xor i32 %x, %y360 %n1 = and i32 %mask, %n0 ; swapped361 %r = xor i32 %x, %n1 ; swapped, %x instead of %y362 ret i32 %r363}364 365; ============================================================================ ;366; Y is an 'and' too.367; ============================================================================ ;368 369define i32 @in_complex_y0(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) {370; CHECK-I-LABEL: in_complex_y0:371; CHECK-I: # %bb.0:372; CHECK-I-NEXT: and a1, a1, a2373; CHECK-I-NEXT: xor a0, a0, a1374; CHECK-I-NEXT: and a0, a0, a3375; CHECK-I-NEXT: xor a0, a0, a1376; CHECK-I-NEXT: ret377;378; CHECK-ZBB-LABEL: in_complex_y0:379; CHECK-ZBB: # %bb.0:380; CHECK-ZBB-NEXT: and a1, a1, a2381; CHECK-ZBB-NEXT: and a0, a0, a3382; CHECK-ZBB-NEXT: andn a1, a1, a3383; CHECK-ZBB-NEXT: or a0, a0, a1384; CHECK-ZBB-NEXT: ret385 %y = and i32 %y_hi, %y_low386 %n0 = xor i32 %x, %y387 %n1 = and i32 %n0, %mask388 %r = xor i32 %n1, %y389 ret i32 %r390}391 392define i32 @in_complex_y1(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) {393; CHECK-I-LABEL: in_complex_y1:394; CHECK-I: # %bb.0:395; CHECK-I-NEXT: and a1, a1, a2396; CHECK-I-NEXT: xor a0, a0, a1397; CHECK-I-NEXT: and a0, a0, a3398; CHECK-I-NEXT: xor a0, a1, a0399; CHECK-I-NEXT: ret400;401; CHECK-ZBB-LABEL: in_complex_y1:402; CHECK-ZBB: # %bb.0:403; CHECK-ZBB-NEXT: and a1, a1, a2404; CHECK-ZBB-NEXT: and a0, a0, a3405; CHECK-ZBB-NEXT: andn a1, a1, a3406; CHECK-ZBB-NEXT: or a0, a0, a1407; CHECK-ZBB-NEXT: ret408 %y = and i32 %y_hi, %y_low409 %n0 = xor i32 %x, %y410 %n1 = and i32 %n0, %mask411 %r = xor i32 %y, %n1412 ret i32 %r413}414 415; ============================================================================ ;416; M is an 'xor' too.417; ============================================================================ ;418 419define i32 @in_complex_m0(i32 %x, i32 %y, i32 %m_a, i32 %m_b) {420; CHECK-I-LABEL: in_complex_m0:421; CHECK-I: # %bb.0:422; CHECK-I-NEXT: xor a2, a2, a3423; CHECK-I-NEXT: xor a0, a0, a1424; CHECK-I-NEXT: and a0, a0, a2425; CHECK-I-NEXT: xor a0, a0, a1426; CHECK-I-NEXT: ret427;428; CHECK-ZBB-LABEL: in_complex_m0:429; CHECK-ZBB: # %bb.0:430; CHECK-ZBB-NEXT: xor a2, a2, a3431; CHECK-ZBB-NEXT: andn a1, a1, a2432; CHECK-ZBB-NEXT: and a0, a0, a2433; CHECK-ZBB-NEXT: or a0, a0, a1434; CHECK-ZBB-NEXT: ret435 %mask = xor i32 %m_a, %m_b436 %n0 = xor i32 %x, %y437 %n1 = and i32 %n0, %mask438 %r = xor i32 %n1, %y439 ret i32 %r440}441 442define i32 @in_complex_m1(i32 %x, i32 %y, i32 %m_a, i32 %m_b) {443; CHECK-I-LABEL: in_complex_m1:444; CHECK-I: # %bb.0:445; CHECK-I-NEXT: xor a2, a2, a3446; CHECK-I-NEXT: xor a0, a0, a1447; CHECK-I-NEXT: and a0, a2, a0448; CHECK-I-NEXT: xor a0, a0, a1449; CHECK-I-NEXT: ret450;451; CHECK-ZBB-LABEL: in_complex_m1:452; CHECK-ZBB: # %bb.0:453; CHECK-ZBB-NEXT: xor a2, a2, a3454; CHECK-ZBB-NEXT: andn a1, a1, a2455; CHECK-ZBB-NEXT: and a0, a0, a2456; CHECK-ZBB-NEXT: or a0, a0, a1457; CHECK-ZBB-NEXT: ret458 %mask = xor i32 %m_a, %m_b459 %n0 = xor i32 %x, %y460 %n1 = and i32 %mask, %n0461 %r = xor i32 %n1, %y462 ret i32 %r463}464 465; ============================================================================ ;466; Both Y and M are complex.467; ============================================================================ ;468 469define i32 @in_complex_y0_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {470; CHECK-I-LABEL: in_complex_y0_m0:471; CHECK-I: # %bb.0:472; CHECK-I-NEXT: and a1, a1, a2473; CHECK-I-NEXT: xor a3, a3, a4474; CHECK-I-NEXT: xor a0, a0, a1475; CHECK-I-NEXT: and a0, a0, a3476; CHECK-I-NEXT: xor a0, a0, a1477; CHECK-I-NEXT: ret478;479; CHECK-ZBB-LABEL: in_complex_y0_m0:480; CHECK-ZBB: # %bb.0:481; CHECK-ZBB-NEXT: and a1, a1, a2482; CHECK-ZBB-NEXT: xor a3, a3, a4483; CHECK-ZBB-NEXT: andn a1, a1, a3484; CHECK-ZBB-NEXT: and a0, a0, a3485; CHECK-ZBB-NEXT: or a0, a0, a1486; CHECK-ZBB-NEXT: ret487 %y = and i32 %y_hi, %y_low488 %mask = xor i32 %m_a, %m_b489 %n0 = xor i32 %x, %y490 %n1 = and i32 %n0, %mask491 %r = xor i32 %n1, %y492 ret i32 %r493}494 495define i32 @in_complex_y1_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {496; CHECK-I-LABEL: in_complex_y1_m0:497; CHECK-I: # %bb.0:498; CHECK-I-NEXT: and a1, a1, a2499; CHECK-I-NEXT: xor a3, a3, a4500; CHECK-I-NEXT: xor a0, a0, a1501; CHECK-I-NEXT: and a0, a0, a3502; CHECK-I-NEXT: xor a0, a1, a0503; CHECK-I-NEXT: ret504;505; CHECK-ZBB-LABEL: in_complex_y1_m0:506; CHECK-ZBB: # %bb.0:507; CHECK-ZBB-NEXT: and a1, a1, a2508; CHECK-ZBB-NEXT: xor a3, a3, a4509; CHECK-ZBB-NEXT: andn a1, a1, a3510; CHECK-ZBB-NEXT: and a0, a0, a3511; CHECK-ZBB-NEXT: or a0, a0, a1512; CHECK-ZBB-NEXT: ret513 %y = and i32 %y_hi, %y_low514 %mask = xor i32 %m_a, %m_b515 %n0 = xor i32 %x, %y516 %n1 = and i32 %n0, %mask517 %r = xor i32 %y, %n1518 ret i32 %r519}520 521define i32 @in_complex_y0_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {522; CHECK-I-LABEL: in_complex_y0_m1:523; CHECK-I: # %bb.0:524; CHECK-I-NEXT: and a1, a1, a2525; CHECK-I-NEXT: xor a3, a3, a4526; CHECK-I-NEXT: xor a0, a0, a1527; CHECK-I-NEXT: and a0, a3, a0528; CHECK-I-NEXT: xor a0, a0, a1529; CHECK-I-NEXT: ret530;531; CHECK-ZBB-LABEL: in_complex_y0_m1:532; CHECK-ZBB: # %bb.0:533; CHECK-ZBB-NEXT: and a1, a1, a2534; CHECK-ZBB-NEXT: xor a3, a3, a4535; CHECK-ZBB-NEXT: andn a1, a1, a3536; CHECK-ZBB-NEXT: and a0, a0, a3537; CHECK-ZBB-NEXT: or a0, a0, a1538; CHECK-ZBB-NEXT: ret539 %y = and i32 %y_hi, %y_low540 %mask = xor i32 %m_a, %m_b541 %n0 = xor i32 %x, %y542 %n1 = and i32 %mask, %n0543 %r = xor i32 %n1, %y544 ret i32 %r545}546 547define i32 @in_complex_y1_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {548; CHECK-I-LABEL: in_complex_y1_m1:549; CHECK-I: # %bb.0:550; CHECK-I-NEXT: and a1, a1, a2551; CHECK-I-NEXT: xor a3, a3, a4552; CHECK-I-NEXT: xor a0, a0, a1553; CHECK-I-NEXT: and a0, a3, a0554; CHECK-I-NEXT: xor a0, a1, a0555; CHECK-I-NEXT: ret556;557; CHECK-ZBB-LABEL: in_complex_y1_m1:558; CHECK-ZBB: # %bb.0:559; CHECK-ZBB-NEXT: and a1, a1, a2560; CHECK-ZBB-NEXT: xor a3, a3, a4561; CHECK-ZBB-NEXT: andn a1, a1, a3562; CHECK-ZBB-NEXT: and a0, a0, a3563; CHECK-ZBB-NEXT: or a0, a0, a1564; CHECK-ZBB-NEXT: ret565 %y = and i32 %y_hi, %y_low566 %mask = xor i32 %m_a, %m_b567 %n0 = xor i32 %x, %y568 %n1 = and i32 %mask, %n0569 %r = xor i32 %y, %n1570 ret i32 %r571}572 573; ============================================================================ ;574; Various cases with %x and/or %y being a constant575; ============================================================================ ;576 577define i32 @out_constant_varx_mone(i32 %x, i32 %y, i32 %mask) {578; CHECK-I-LABEL: out_constant_varx_mone:579; CHECK-I: # %bb.0:580; CHECK-I-NEXT: not a1, a2581; CHECK-I-NEXT: and a0, a2, a0582; CHECK-I-NEXT: or a0, a0, a1583; CHECK-I-NEXT: ret584;585; CHECK-ZBB-LABEL: out_constant_varx_mone:586; CHECK-ZBB: # %bb.0:587; CHECK-ZBB-NEXT: and a0, a2, a0588; CHECK-ZBB-NEXT: orn a0, a0, a2589; CHECK-ZBB-NEXT: ret590 %notmask = xor i32 %mask, -1591 %mx = and i32 %mask, %x592 %my = and i32 %notmask, -1593 %r = or i32 %mx, %my594 ret i32 %r595}596 597define i32 @in_constant_varx_mone(i32 %x, i32 %y, i32 %mask) {598; CHECK-I-LABEL: in_constant_varx_mone:599; CHECK-I: # %bb.0:600; CHECK-I-NEXT: not a0, a0601; CHECK-I-NEXT: and a0, a0, a2602; CHECK-I-NEXT: not a0, a0603; CHECK-I-NEXT: ret604;605; CHECK-ZBB-LABEL: in_constant_varx_mone:606; CHECK-ZBB: # %bb.0:607; CHECK-ZBB-NEXT: andn a0, a2, a0608; CHECK-ZBB-NEXT: not a0, a0609; CHECK-ZBB-NEXT: ret610 %n0 = xor i32 %x, -1 ; %x611 %n1 = and i32 %n0, %mask612 %r = xor i32 %n1, -1613 ret i32 %r614}615 616; This is not a canonical form. Testing for completeness only.617define i32 @out_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) {618; CHECK-LABEL: out_constant_varx_mone_invmask:619; CHECK: # %bb.0:620; CHECK-NEXT: or a0, a0, a2621; CHECK-NEXT: ret622 %notmask = xor i32 %mask, -1623 %mx = and i32 %notmask, %x624 %my = and i32 %mask, -1625 %r = or i32 %mx, %my626 ret i32 %r627}628 629; This is not a canonical form. Testing for completeness only.630define i32 @in_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) {631; CHECK-I-LABEL: in_constant_varx_mone_invmask:632; CHECK-I: # %bb.0:633; CHECK-I-NEXT: not a1, a2634; CHECK-I-NEXT: not a0, a0635; CHECK-I-NEXT: and a0, a0, a1636; CHECK-I-NEXT: not a0, a0637; CHECK-I-NEXT: ret638;639; CHECK-ZBB-LABEL: in_constant_varx_mone_invmask:640; CHECK-ZBB: # %bb.0:641; CHECK-ZBB-NEXT: not a0, a0642; CHECK-ZBB-NEXT: andn a0, a0, a2643; CHECK-ZBB-NEXT: not a0, a0644; CHECK-ZBB-NEXT: ret645 %notmask = xor i32 %mask, -1646 %n0 = xor i32 %x, -1 ; %x647 %n1 = and i32 %n0, %notmask648 %r = xor i32 %n1, -1649 ret i32 %r650}651 652define i32 @out_constant_varx_42(i32 %x, i32 %y, i32 %mask) {653; CHECK-I-LABEL: out_constant_varx_42:654; CHECK-I: # %bb.0:655; CHECK-I-NEXT: xori a0, a0, 42656; CHECK-I-NEXT: and a0, a0, a2657; CHECK-I-NEXT: xori a0, a0, 42658; CHECK-I-NEXT: ret659;660; CHECK-ZBB-LABEL: out_constant_varx_42:661; CHECK-ZBB: # %bb.0:662; CHECK-ZBB-NEXT: and a0, a2, a0663; CHECK-ZBB-NEXT: li a1, 42664; CHECK-ZBB-NEXT: andn a1, a1, a2665; CHECK-ZBB-NEXT: or a0, a0, a1666; CHECK-ZBB-NEXT: ret667 %notmask = xor i32 %mask, -1668 %mx = and i32 %mask, %x669 %my = and i32 %notmask, 42670 %r = or i32 %mx, %my671 ret i32 %r672}673 674define i32 @in_constant_varx_42(i32 %x, i32 %y, i32 %mask) {675; CHECK-I-LABEL: in_constant_varx_42:676; CHECK-I: # %bb.0:677; CHECK-I-NEXT: xori a0, a0, 42678; CHECK-I-NEXT: and a0, a0, a2679; CHECK-I-NEXT: xori a0, a0, 42680; CHECK-I-NEXT: ret681;682; CHECK-ZBB-LABEL: in_constant_varx_42:683; CHECK-ZBB: # %bb.0:684; CHECK-ZBB-NEXT: andn a0, a2, a0685; CHECK-ZBB-NEXT: ori a1, a2, 42686; CHECK-ZBB-NEXT: andn a0, a1, a0687; CHECK-ZBB-NEXT: ret688 %n0 = xor i32 %x, 42 ; %x689 %n1 = and i32 %n0, %mask690 %r = xor i32 %n1, 42691 ret i32 %r692}693 694; This is not a canonical form. Testing for completeness only.695define i32 @out_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) {696; CHECK-I-LABEL: out_constant_varx_42_invmask:697; CHECK-I: # %bb.0:698; CHECK-I-NEXT: xori a1, a0, 42699; CHECK-I-NEXT: and a1, a1, a2700; CHECK-I-NEXT: xor a0, a1, a0701; CHECK-I-NEXT: ret702;703; CHECK-ZBB-LABEL: out_constant_varx_42_invmask:704; CHECK-ZBB: # %bb.0:705; CHECK-ZBB-NEXT: andn a0, a0, a2706; CHECK-ZBB-NEXT: andi a1, a2, 42707; CHECK-ZBB-NEXT: or a0, a0, a1708; CHECK-ZBB-NEXT: ret709 %notmask = xor i32 %mask, -1710 %mx = and i32 %notmask, %x711 %my = and i32 %mask, 42712 %r = or i32 %mx, %my713 ret i32 %r714}715 716; This is not a canonical form. Testing for completeness only.717define i32 @in_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) {718; CHECK-I-LABEL: in_constant_varx_42_invmask:719; CHECK-I: # %bb.0:720; CHECK-I-NEXT: not a1, a2721; CHECK-I-NEXT: xori a0, a0, 42722; CHECK-I-NEXT: and a0, a0, a1723; CHECK-I-NEXT: xori a0, a0, 42724; CHECK-I-NEXT: ret725;726; CHECK-ZBB-LABEL: in_constant_varx_42_invmask:727; CHECK-ZBB: # %bb.0:728; CHECK-ZBB-NEXT: andn a0, a0, a2729; CHECK-ZBB-NEXT: andi a1, a2, 42730; CHECK-ZBB-NEXT: or a0, a0, a1731; CHECK-ZBB-NEXT: ret732 %notmask = xor i32 %mask, -1733 %n0 = xor i32 %x, 42 ; %x734 %n1 = and i32 %n0, %notmask735 %r = xor i32 %n1, 42736 ret i32 %r737}738 739define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {740; CHECK-LABEL: out_constant_mone_vary:741; CHECK: # %bb.0:742; CHECK-NEXT: or a0, a1, a2743; CHECK-NEXT: ret744 %notmask = xor i32 %mask, -1745 %mx = and i32 %mask, -1746 %my = and i32 %notmask, %y747 %r = or i32 %mx, %my748 ret i32 %r749}750 751define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {752; CHECK-LABEL: in_constant_mone_vary:753; CHECK: # %bb.0:754; CHECK-NEXT: or a0, a2, a1755; CHECK-NEXT: ret756 %n0 = xor i32 -1, %y ; %x757 %n1 = and i32 %n0, %mask758 %r = xor i32 %n1, %y759 ret i32 %r760}761 762; This is not a canonical form. Testing for completeness only.763define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {764; CHECK-I-LABEL: out_constant_mone_vary_invmask:765; CHECK-I: # %bb.0:766; CHECK-I-NEXT: not a0, a2767; CHECK-I-NEXT: and a1, a2, a1768; CHECK-I-NEXT: or a0, a0, a1769; CHECK-I-NEXT: ret770;771; CHECK-ZBB-LABEL: out_constant_mone_vary_invmask:772; CHECK-ZBB: # %bb.0:773; CHECK-ZBB-NEXT: and a1, a2, a1774; CHECK-ZBB-NEXT: orn a0, a1, a2775; CHECK-ZBB-NEXT: ret776 %notmask = xor i32 %mask, -1777 %mx = and i32 %notmask, -1778 %my = and i32 %mask, %y779 %r = or i32 %mx, %my780 ret i32 %r781}782 783; This is not a canonical form. Testing for completeness only.784define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {785; CHECK-I-LABEL: in_constant_mone_vary_invmask:786; CHECK-I: # %bb.0:787; CHECK-I-NEXT: not a0, a2788; CHECK-I-NEXT: or a0, a0, a1789; CHECK-I-NEXT: ret790;791; CHECK-ZBB-LABEL: in_constant_mone_vary_invmask:792; CHECK-ZBB: # %bb.0:793; CHECK-ZBB-NEXT: orn a0, a1, a2794; CHECK-ZBB-NEXT: ret795 %notmask = xor i32 %mask, -1796 %n0 = xor i32 -1, %y ; %x797 %n1 = and i32 %n0, %notmask798 %r = xor i32 %n1, %y799 ret i32 %r800}801 802define i32 @out_constant_42_vary(i32 %x, i32 %y, i32 %mask) {803; CHECK-I-LABEL: out_constant_42_vary:804; CHECK-I: # %bb.0:805; CHECK-I-NEXT: xori a0, a1, 42806; CHECK-I-NEXT: and a0, a0, a2807; CHECK-I-NEXT: xor a0, a0, a1808; CHECK-I-NEXT: ret809;810; CHECK-ZBB-LABEL: out_constant_42_vary:811; CHECK-ZBB: # %bb.0:812; CHECK-ZBB-NEXT: andi a0, a2, 42813; CHECK-ZBB-NEXT: andn a1, a1, a2814; CHECK-ZBB-NEXT: or a0, a0, a1815; CHECK-ZBB-NEXT: ret816 %notmask = xor i32 %mask, -1817 %mx = and i32 %mask, 42818 %my = and i32 %notmask, %y819 %r = or i32 %mx, %my820 ret i32 %r821}822 823define i32 @in_constant_42_vary(i32 %x, i32 %y, i32 %mask) {824; CHECK-I-LABEL: in_constant_42_vary:825; CHECK-I: # %bb.0:826; CHECK-I-NEXT: xori a0, a1, 42827; CHECK-I-NEXT: and a0, a0, a2828; CHECK-I-NEXT: xor a0, a0, a1829; CHECK-I-NEXT: ret830;831; CHECK-ZBB-LABEL: in_constant_42_vary:832; CHECK-ZBB: # %bb.0:833; CHECK-ZBB-NEXT: andn a0, a1, a2834; CHECK-ZBB-NEXT: andi a1, a2, 42835; CHECK-ZBB-NEXT: or a0, a1, a0836; CHECK-ZBB-NEXT: ret837 %n0 = xor i32 42, %y ; %x838 %n1 = and i32 %n0, %mask839 %r = xor i32 %n1, %y840 ret i32 %r841}842 843; This is not a canonical form. Testing for completeness only.844define i32 @out_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) {845; CHECK-I-LABEL: out_constant_42_vary_invmask:846; CHECK-I: # %bb.0:847; CHECK-I-NEXT: xori a0, a1, 42848; CHECK-I-NEXT: and a0, a0, a2849; CHECK-I-NEXT: xori a0, a0, 42850; CHECK-I-NEXT: ret851;852; CHECK-ZBB-LABEL: out_constant_42_vary_invmask:853; CHECK-ZBB: # %bb.0:854; CHECK-ZBB-NEXT: li a0, 42855; CHECK-ZBB-NEXT: andn a0, a0, a2856; CHECK-ZBB-NEXT: and a1, a2, a1857; CHECK-ZBB-NEXT: or a0, a0, a1858; CHECK-ZBB-NEXT: ret859 %notmask = xor i32 %mask, -1860 %mx = and i32 %notmask, 42861 %my = and i32 %mask, %y862 %r = or i32 %mx, %my863 ret i32 %r864}865 866; This is not a canonical form. Testing for completeness only.867define i32 @in_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) {868; CHECK-I-LABEL: in_constant_42_vary_invmask:869; CHECK-I: # %bb.0:870; CHECK-I-NEXT: not a0, a2871; CHECK-I-NEXT: xori a2, a1, 42872; CHECK-I-NEXT: and a0, a2, a0873; CHECK-I-NEXT: xor a0, a0, a1874; CHECK-I-NEXT: ret875;876; CHECK-ZBB-LABEL: in_constant_42_vary_invmask:877; CHECK-ZBB: # %bb.0:878; CHECK-ZBB-NEXT: andn a0, a2, a1879; CHECK-ZBB-NEXT: ori a1, a2, 42880; CHECK-ZBB-NEXT: andn a0, a1, a0881; CHECK-ZBB-NEXT: ret882 %notmask = xor i32 %mask, -1883 %n0 = xor i32 42, %y ; %x884 %n1 = and i32 %n0, %notmask885 %r = xor i32 %n1, %y886 ret i32 %r887}888 889; ============================================================================ ;890; Negative tests. Should not be folded.891; ============================================================================ ;892 893; Multi-use tests.894declare void @use32(i32) nounwind895define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {896; RV32-LABEL: in_multiuse_A:897; RV32: # %bb.0:898; RV32-NEXT: addi sp, sp, -16899; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill900; RV32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill901; RV32-NEXT: sw s1, 4(sp) # 4-byte Folded Spill902; RV32-NEXT: mv s0, a1903; RV32-NEXT: xor a0, a0, a1904; RV32-NEXT: and s1, a0, a3905; RV32-NEXT: mv a0, s1906; RV32-NEXT: call use32907; RV32-NEXT: xor a0, s1, s0908; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload909; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload910; RV32-NEXT: lw s1, 4(sp) # 4-byte Folded Reload911; RV32-NEXT: addi sp, sp, 16912; RV32-NEXT: ret913;914; RV64-LABEL: in_multiuse_A:915; RV64: # %bb.0:916; RV64-NEXT: addi sp, sp, -32917; RV64-NEXT: sd ra, 24(sp) # 8-byte Folded Spill918; RV64-NEXT: sd s0, 16(sp) # 8-byte Folded Spill919; RV64-NEXT: sd s1, 8(sp) # 8-byte Folded Spill920; RV64-NEXT: mv s0, a1921; RV64-NEXT: xor a0, a0, a1922; RV64-NEXT: and s1, a0, a3923; RV64-NEXT: mv a0, s1924; RV64-NEXT: call use32925; RV64-NEXT: xor a0, s1, s0926; RV64-NEXT: ld ra, 24(sp) # 8-byte Folded Reload927; RV64-NEXT: ld s0, 16(sp) # 8-byte Folded Reload928; RV64-NEXT: ld s1, 8(sp) # 8-byte Folded Reload929; RV64-NEXT: addi sp, sp, 32930; RV64-NEXT: ret931 %n0 = xor i32 %x, %y932 %n1 = and i32 %n0, %mask933 call void @use32(i32 %n1)934 %r = xor i32 %n1, %y935 ret i32 %r936}937 938define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {939; RV32-LABEL: in_multiuse_B:940; RV32: # %bb.0:941; RV32-NEXT: addi sp, sp, -16942; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill943; RV32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill944; RV32-NEXT: sw s1, 4(sp) # 4-byte Folded Spill945; RV32-NEXT: mv s0, a1946; RV32-NEXT: xor a0, a0, a1947; RV32-NEXT: and s1, a0, a3948; RV32-NEXT: call use32949; RV32-NEXT: xor a0, s1, s0950; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload951; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload952; RV32-NEXT: lw s1, 4(sp) # 4-byte Folded Reload953; RV32-NEXT: addi sp, sp, 16954; RV32-NEXT: ret955;956; RV64-LABEL: in_multiuse_B:957; RV64: # %bb.0:958; RV64-NEXT: addi sp, sp, -32959; RV64-NEXT: sd ra, 24(sp) # 8-byte Folded Spill960; RV64-NEXT: sd s0, 16(sp) # 8-byte Folded Spill961; RV64-NEXT: sd s1, 8(sp) # 8-byte Folded Spill962; RV64-NEXT: mv s0, a1963; RV64-NEXT: xor a0, a0, a1964; RV64-NEXT: and s1, a0, a3965; RV64-NEXT: call use32966; RV64-NEXT: xor a0, s1, s0967; RV64-NEXT: ld ra, 24(sp) # 8-byte Folded Reload968; RV64-NEXT: ld s0, 16(sp) # 8-byte Folded Reload969; RV64-NEXT: ld s1, 8(sp) # 8-byte Folded Reload970; RV64-NEXT: addi sp, sp, 32971; RV64-NEXT: ret972 %n0 = xor i32 %x, %y973 %n1 = and i32 %n0, %mask974 call void @use32(i32 %n0)975 %r = xor i32 %n1, %y976 ret i32 %r977}978 979; Various bad variants980define i32 @n0_badmask(i32 %x, i32 %y, i32 %mask, i32 %mask2) {981; CHECK-I-LABEL: n0_badmask:982; CHECK-I: # %bb.0:983; CHECK-I-NEXT: and a0, a0, a2984; CHECK-I-NEXT: not a2, a3985; CHECK-I-NEXT: and a1, a1, a2986; CHECK-I-NEXT: or a0, a0, a1987; CHECK-I-NEXT: ret988;989; CHECK-ZBB-LABEL: n0_badmask:990; CHECK-ZBB: # %bb.0:991; CHECK-ZBB-NEXT: and a0, a0, a2992; CHECK-ZBB-NEXT: andn a1, a1, a3993; CHECK-ZBB-NEXT: or a0, a0, a1994; CHECK-ZBB-NEXT: ret995 %mx = and i32 %x, %mask996 %notmask = xor i32 %mask2, -1 ; %mask2 instead of %mask997 %my = and i32 %y, %notmask998 %r = or i32 %mx, %my999 ret i32 %r1000}1001 1002define i32 @n0_badxor(i32 %x, i32 %y, i32 %mask) {1003; CHECK-LABEL: n0_badxor:1004; CHECK: # %bb.0:1005; CHECK-NEXT: and a0, a0, a21006; CHECK-NEXT: xori a2, a2, 11007; CHECK-NEXT: and a1, a1, a21008; CHECK-NEXT: or a0, a0, a11009; CHECK-NEXT: ret1010 %mx = and i32 %x, %mask1011 %notmask = xor i32 %mask, 1 ; instead of -11012 %my = and i32 %y, %notmask1013 %r = or i32 %mx, %my1014 ret i32 %r1015}1016 1017define i32 @n1_thirdvar(i32 %x, i32 %y, i32 %z, i32 %mask) {1018; CHECK-LABEL: n1_thirdvar:1019; CHECK: # %bb.0:1020; CHECK-NEXT: xor a0, a0, a11021; CHECK-NEXT: and a0, a0, a31022; CHECK-NEXT: xor a0, a0, a21023; CHECK-NEXT: ret1024 %n0 = xor i32 %x, %y1025 %n1 = and i32 %n0, %mask1026 %r = xor i32 %n1, %z ; instead of %y1027 ret i32 %r1028}1029