1002 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \3; RUN: | FileCheck %s -check-prefixes=CHECK,RV64I4; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs < %s \5; RUN: | FileCheck %s -check-prefixes=CHECK,RV64ZBB-ZBKB6; RUN: llc -mtriple=riscv64 -mattr=+zbkb -verify-machineinstrs < %s \7; RUN: | FileCheck %s -check-prefixes=CHECK,RV64ZBB-ZBKB8 9define signext i32 @andn_i32(i32 signext %a, i32 signext %b) nounwind {10; RV64I-LABEL: andn_i32:11; RV64I: # %bb.0:12; RV64I-NEXT: not a1, a113; RV64I-NEXT: and a0, a1, a014; RV64I-NEXT: ret15;16; RV64ZBB-ZBKB-LABEL: andn_i32:17; RV64ZBB-ZBKB: # %bb.0:18; RV64ZBB-ZBKB-NEXT: andn a0, a0, a119; RV64ZBB-ZBKB-NEXT: ret20 %neg = xor i32 %b, -121 %and = and i32 %neg, %a22 ret i32 %and23}24 25define i64 @andn_i64(i64 %a, i64 %b) nounwind {26; RV64I-LABEL: andn_i64:27; RV64I: # %bb.0:28; RV64I-NEXT: not a1, a129; RV64I-NEXT: and a0, a1, a030; RV64I-NEXT: ret31;32; RV64ZBB-ZBKB-LABEL: andn_i64:33; RV64ZBB-ZBKB: # %bb.0:34; RV64ZBB-ZBKB-NEXT: andn a0, a0, a135; RV64ZBB-ZBKB-NEXT: ret36 %neg = xor i64 %b, -137 %and = and i64 %neg, %a38 ret i64 %and39}40 41define signext i32 @orn_i32(i32 signext %a, i32 signext %b) nounwind {42; RV64I-LABEL: orn_i32:43; RV64I: # %bb.0:44; RV64I-NEXT: not a1, a145; RV64I-NEXT: or a0, a1, a046; RV64I-NEXT: ret47;48; RV64ZBB-ZBKB-LABEL: orn_i32:49; RV64ZBB-ZBKB: # %bb.0:50; RV64ZBB-ZBKB-NEXT: orn a0, a0, a151; RV64ZBB-ZBKB-NEXT: ret52 %neg = xor i32 %b, -153 %or = or i32 %neg, %a54 ret i32 %or55}56 57define i64 @orn_i64(i64 %a, i64 %b) nounwind {58; RV64I-LABEL: orn_i64:59; RV64I: # %bb.0:60; RV64I-NEXT: not a1, a161; RV64I-NEXT: or a0, a1, a062; RV64I-NEXT: ret63;64; RV64ZBB-ZBKB-LABEL: orn_i64:65; RV64ZBB-ZBKB: # %bb.0:66; RV64ZBB-ZBKB-NEXT: orn a0, a0, a167; RV64ZBB-ZBKB-NEXT: ret68 %neg = xor i64 %b, -169 %or = or i64 %neg, %a70 ret i64 %or71}72 73define signext i32 @xnor_i32(i32 signext %a, i32 signext %b) nounwind {74; RV64I-LABEL: xnor_i32:75; RV64I: # %bb.0:76; RV64I-NEXT: xor a0, a0, a177; RV64I-NEXT: not a0, a078; RV64I-NEXT: ret79;80; RV64ZBB-ZBKB-LABEL: xnor_i32:81; RV64ZBB-ZBKB: # %bb.0:82; RV64ZBB-ZBKB-NEXT: xnor a0, a0, a183; RV64ZBB-ZBKB-NEXT: ret84 %neg = xor i32 %a, -185 %xor = xor i32 %neg, %b86 ret i32 %xor87}88 89define i64 @xnor_i64(i64 %a, i64 %b) nounwind {90; RV64I-LABEL: xnor_i64:91; RV64I: # %bb.0:92; RV64I-NEXT: xor a0, a0, a193; RV64I-NEXT: not a0, a094; RV64I-NEXT: ret95;96; RV64ZBB-ZBKB-LABEL: xnor_i64:97; RV64ZBB-ZBKB: # %bb.0:98; RV64ZBB-ZBKB-NEXT: xnor a0, a0, a199; RV64ZBB-ZBKB-NEXT: ret100 %neg = xor i64 %a, -1101 %xor = xor i64 %neg, %b102 ret i64 %xor103}104 105define signext i32 @disjoint_or_xnor_i32(i32 signext %a, i32 signext %b) nounwind {106; CHECK-LABEL: disjoint_or_xnor_i32:107; CHECK: # %bb.0:108; CHECK-NEXT: or a0, a0, a1109; CHECK-NEXT: not a0, a0110; CHECK-NEXT: ret111 %or = or disjoint i32 %a, %b112 %not = xor i32 %or, -1113 ret i32 %not114}115 116define i64 @disjoint_or_xnor_i64(i64 %a, i64 %b) nounwind {117; RV64I-LABEL: disjoint_or_xnor_i64:118; RV64I: # %bb.0:119; RV64I-NEXT: or a0, a0, a1120; RV64I-NEXT: not a0, a0121; RV64I-NEXT: ret122;123; RV64ZBB-ZBKB-LABEL: disjoint_or_xnor_i64:124; RV64ZBB-ZBKB: # %bb.0:125; RV64ZBB-ZBKB-NEXT: xnor a0, a0, a1126; RV64ZBB-ZBKB-NEXT: ret127 %or = or disjoint i64 %a, %b128 %not = xor i64 %or, -1129 ret i64 %not130}131 132define signext i32 @disjoint_or_xnor_knownbits_i32(i32 signext %x, i32 signext %y, i32 signext %z) nounwind {133; RV64I-LABEL: disjoint_or_xnor_knownbits_i32:134; RV64I: # %bb.0:135; RV64I-NEXT: andi a0, a0, 126136; RV64I-NEXT: andi a1, a1, -127137; RV64I-NEXT: or a0, a0, a1138; RV64I-NEXT: not a0, a0139; RV64I-NEXT: ret140;141; RV64ZBB-ZBKB-LABEL: disjoint_or_xnor_knownbits_i32:142; RV64ZBB-ZBKB: # %bb.0:143; RV64ZBB-ZBKB-NEXT: andi a0, a0, 126144; RV64ZBB-ZBKB-NEXT: andi a1, a1, -127145; RV64ZBB-ZBKB-NEXT: xnor a0, a0, a1146; RV64ZBB-ZBKB-NEXT: ret147 %a = and i32 %x, 126148 %b = and i32 %y, -127149 %or = or i32 %a, %b150 %not = xor i32 %or, -1151 ret i32 %not152}153 154define i64 @disjoint_or_xnor_knownbits_i64(i64 %x, i64 %y, i64 %z) nounwind {155; RV64I-LABEL: disjoint_or_xnor_knownbits_i64:156; RV64I: # %bb.0:157; RV64I-NEXT: andi a0, a0, 126158; RV64I-NEXT: andi a1, a1, -127159; RV64I-NEXT: or a0, a0, a1160; RV64I-NEXT: not a0, a0161; RV64I-NEXT: ret162;163; RV64ZBB-ZBKB-LABEL: disjoint_or_xnor_knownbits_i64:164; RV64ZBB-ZBKB: # %bb.0:165; RV64ZBB-ZBKB-NEXT: andi a0, a0, 126166; RV64ZBB-ZBKB-NEXT: andi a1, a1, -127167; RV64ZBB-ZBKB-NEXT: xnor a0, a0, a1168; RV64ZBB-ZBKB-NEXT: ret169 %a = and i64 %x, 126170 %b = and i64 %y, -127171 %or = or i64 %a, %b172 %not = xor i64 %or, -1173 ret i64 %not174}175 176define signext i32 @inverted_masked_merge_i32(i32 signext %x, i32 signext %y, i32 signext %z) nounwind {177; RV64I-LABEL: inverted_masked_merge_i32:178; RV64I: # %bb.0:179; RV64I-NEXT: xor a1, a1, a2180; RV64I-NEXT: and a0, a1, a0181; RV64I-NEXT: xor a0, a0, a2182; RV64I-NEXT: not a0, a0183; RV64I-NEXT: ret184;185; RV64ZBB-ZBKB-LABEL: inverted_masked_merge_i32:186; RV64ZBB-ZBKB: # %bb.0:187; RV64ZBB-ZBKB-NEXT: and a1, a0, a1188; RV64ZBB-ZBKB-NEXT: andn a0, a2, a0189; RV64ZBB-ZBKB-NEXT: xnor a0, a1, a0190; RV64ZBB-ZBKB-NEXT: ret191 %a = and i32 %x, %y192 %notx = xor i32 %x, -1193 %b = and i32 %notx, %z194 %or = or i32 %a, %b195 %not = xor i32 %or, -1196 ret i32 %not197}198 199define i64 @inverted_masked_merge_i64(i64 %x, i64 %y, i64 %z) nounwind {200; RV64I-LABEL: inverted_masked_merge_i64:201; RV64I: # %bb.0:202; RV64I-NEXT: xor a1, a1, a2203; RV64I-NEXT: and a0, a1, a0204; RV64I-NEXT: xor a0, a0, a2205; RV64I-NEXT: not a0, a0206; RV64I-NEXT: ret207;208; RV64ZBB-ZBKB-LABEL: inverted_masked_merge_i64:209; RV64ZBB-ZBKB: # %bb.0:210; RV64ZBB-ZBKB-NEXT: and a1, a0, a1211; RV64ZBB-ZBKB-NEXT: andn a0, a2, a0212; RV64ZBB-ZBKB-NEXT: xnor a0, a1, a0213; RV64ZBB-ZBKB-NEXT: ret214 %a = and i64 %x, %y215 %notx = xor i64 %x, -1216 %b = and i64 %notx, %z217 %or = or i64 %a, %b218 %not = xor i64 %or, -1219 ret i64 %not220}221 222define signext i32 @rol_i32(i32 signext %a, i32 signext %b) nounwind {223; RV64I-LABEL: rol_i32:224; RV64I: # %bb.0:225; RV64I-NEXT: sllw a2, a0, a1226; RV64I-NEXT: neg a1, a1227; RV64I-NEXT: srlw a0, a0, a1228; RV64I-NEXT: or a0, a2, a0229; RV64I-NEXT: ret230;231; RV64ZBB-ZBKB-LABEL: rol_i32:232; RV64ZBB-ZBKB: # %bb.0:233; RV64ZBB-ZBKB-NEXT: rolw a0, a0, a1234; RV64ZBB-ZBKB-NEXT: ret235 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)236 ret i32 %1237}238 239; Similar to rol_i32, but doesn't sign extend the result.240define void @rol_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind {241; RV64I-LABEL: rol_i32_nosext:242; RV64I: # %bb.0:243; RV64I-NEXT: sllw a3, a0, a1244; RV64I-NEXT: neg a1, a1245; RV64I-NEXT: srlw a0, a0, a1246; RV64I-NEXT: or a0, a3, a0247; RV64I-NEXT: sw a0, 0(a2)248; RV64I-NEXT: ret249;250; RV64ZBB-ZBKB-LABEL: rol_i32_nosext:251; RV64ZBB-ZBKB: # %bb.0:252; RV64ZBB-ZBKB-NEXT: rolw a0, a0, a1253; RV64ZBB-ZBKB-NEXT: sw a0, 0(a2)254; RV64ZBB-ZBKB-NEXT: ret255 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)256 store i32 %1, ptr %x257 ret void258}259 260define signext i32 @rol_i32_neg_constant_rhs(i32 signext %a) nounwind {261; RV64I-LABEL: rol_i32_neg_constant_rhs:262; RV64I: # %bb.0:263; RV64I-NEXT: li a1, -2264; RV64I-NEXT: neg a2, a0265; RV64I-NEXT: sllw a0, a1, a0266; RV64I-NEXT: srlw a1, a1, a2267; RV64I-NEXT: or a0, a0, a1268; RV64I-NEXT: ret269;270; RV64ZBB-ZBKB-LABEL: rol_i32_neg_constant_rhs:271; RV64ZBB-ZBKB: # %bb.0:272; RV64ZBB-ZBKB-NEXT: li a1, -2273; RV64ZBB-ZBKB-NEXT: rolw a0, a1, a0274; RV64ZBB-ZBKB-NEXT: ret275 %1 = tail call i32 @llvm.fshl.i32(i32 -2, i32 -2, i32 %a)276 ret i32 %1277}278 279define i64 @rol_i64(i64 %a, i64 %b) nounwind {280; RV64I-LABEL: rol_i64:281; RV64I: # %bb.0:282; RV64I-NEXT: sll a2, a0, a1283; RV64I-NEXT: neg a1, a1284; RV64I-NEXT: srl a0, a0, a1285; RV64I-NEXT: or a0, a2, a0286; RV64I-NEXT: ret287;288; RV64ZBB-ZBKB-LABEL: rol_i64:289; RV64ZBB-ZBKB: # %bb.0:290; RV64ZBB-ZBKB-NEXT: rol a0, a0, a1291; RV64ZBB-ZBKB-NEXT: ret292 %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)293 ret i64 %or294}295 296define signext i32 @ror_i32(i32 signext %a, i32 signext %b) nounwind {297; RV64I-LABEL: ror_i32:298; RV64I: # %bb.0:299; RV64I-NEXT: srlw a2, a0, a1300; RV64I-NEXT: neg a1, a1301; RV64I-NEXT: sllw a0, a0, a1302; RV64I-NEXT: or a0, a2, a0303; RV64I-NEXT: ret304;305; RV64ZBB-ZBKB-LABEL: ror_i32:306; RV64ZBB-ZBKB: # %bb.0:307; RV64ZBB-ZBKB-NEXT: rorw a0, a0, a1308; RV64ZBB-ZBKB-NEXT: ret309 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)310 ret i32 %1311}312 313; Similar to ror_i32, but doesn't sign extend the result.314define void @ror_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind {315; RV64I-LABEL: ror_i32_nosext:316; RV64I: # %bb.0:317; RV64I-NEXT: srlw a3, a0, a1318; RV64I-NEXT: neg a1, a1319; RV64I-NEXT: sllw a0, a0, a1320; RV64I-NEXT: or a0, a3, a0321; RV64I-NEXT: sw a0, 0(a2)322; RV64I-NEXT: ret323;324; RV64ZBB-ZBKB-LABEL: ror_i32_nosext:325; RV64ZBB-ZBKB: # %bb.0:326; RV64ZBB-ZBKB-NEXT: rorw a0, a0, a1327; RV64ZBB-ZBKB-NEXT: sw a0, 0(a2)328; RV64ZBB-ZBKB-NEXT: ret329 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)330 store i32 %1, ptr %x331 ret void332}333 334define signext i32 @ror_i32_neg_constant_rhs(i32 signext %a) nounwind {335; RV64I-LABEL: ror_i32_neg_constant_rhs:336; RV64I: # %bb.0:337; RV64I-NEXT: li a1, -2338; RV64I-NEXT: neg a2, a0339; RV64I-NEXT: srlw a0, a1, a0340; RV64I-NEXT: sllw a1, a1, a2341; RV64I-NEXT: or a0, a0, a1342; RV64I-NEXT: ret343;344; RV64ZBB-ZBKB-LABEL: ror_i32_neg_constant_rhs:345; RV64ZBB-ZBKB: # %bb.0:346; RV64ZBB-ZBKB-NEXT: li a1, -2347; RV64ZBB-ZBKB-NEXT: rorw a0, a1, a0348; RV64ZBB-ZBKB-NEXT: ret349 %1 = tail call i32 @llvm.fshr.i32(i32 -2, i32 -2, i32 %a)350 ret i32 %1351}352 353define i64 @ror_i64(i64 %a, i64 %b) nounwind {354; RV64I-LABEL: ror_i64:355; RV64I: # %bb.0:356; RV64I-NEXT: srl a2, a0, a1357; RV64I-NEXT: neg a1, a1358; RV64I-NEXT: sll a0, a0, a1359; RV64I-NEXT: or a0, a2, a0360; RV64I-NEXT: ret361;362; RV64ZBB-ZBKB-LABEL: ror_i64:363; RV64ZBB-ZBKB: # %bb.0:364; RV64ZBB-ZBKB-NEXT: ror a0, a0, a1365; RV64ZBB-ZBKB-NEXT: ret366 %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)367 ret i64 %or368}369 370define signext i32 @rori_i32_fshl(i32 signext %a) nounwind {371; RV64I-LABEL: rori_i32_fshl:372; RV64I: # %bb.0:373; RV64I-NEXT: srliw a1, a0, 1374; RV64I-NEXT: slliw a0, a0, 31375; RV64I-NEXT: or a0, a0, a1376; RV64I-NEXT: ret377;378; RV64ZBB-ZBKB-LABEL: rori_i32_fshl:379; RV64ZBB-ZBKB: # %bb.0:380; RV64ZBB-ZBKB-NEXT: roriw a0, a0, 1381; RV64ZBB-ZBKB-NEXT: ret382 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)383 ret i32 %1384}385 386; Similar to rori_i32_fshl, but doesn't sign extend the result.387define void @rori_i32_fshl_nosext(i32 signext %a, ptr %x) nounwind {388; RV64I-LABEL: rori_i32_fshl_nosext:389; RV64I: # %bb.0:390; RV64I-NEXT: srliw a2, a0, 1391; RV64I-NEXT: slli a0, a0, 31392; RV64I-NEXT: or a0, a0, a2393; RV64I-NEXT: sw a0, 0(a1)394; RV64I-NEXT: ret395;396; RV64ZBB-ZBKB-LABEL: rori_i32_fshl_nosext:397; RV64ZBB-ZBKB: # %bb.0:398; RV64ZBB-ZBKB-NEXT: roriw a0, a0, 1399; RV64ZBB-ZBKB-NEXT: sw a0, 0(a1)400; RV64ZBB-ZBKB-NEXT: ret401 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)402 store i32 %1, ptr %x403 ret void404}405 406define signext i32 @rori_i32_fshr(i32 signext %a) nounwind {407; RV64I-LABEL: rori_i32_fshr:408; RV64I: # %bb.0:409; RV64I-NEXT: slliw a1, a0, 1410; RV64I-NEXT: srliw a0, a0, 31411; RV64I-NEXT: or a0, a0, a1412; RV64I-NEXT: ret413;414; RV64ZBB-ZBKB-LABEL: rori_i32_fshr:415; RV64ZBB-ZBKB: # %bb.0:416; RV64ZBB-ZBKB-NEXT: roriw a0, a0, 31417; RV64ZBB-ZBKB-NEXT: ret418 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)419 ret i32 %1420}421 422; Similar to rori_i32_fshr, but doesn't sign extend the result.423define void @rori_i32_fshr_nosext(i32 signext %a, ptr %x) nounwind {424; RV64I-LABEL: rori_i32_fshr_nosext:425; RV64I: # %bb.0:426; RV64I-NEXT: slli a2, a0, 1427; RV64I-NEXT: srliw a0, a0, 31428; RV64I-NEXT: or a0, a0, a2429; RV64I-NEXT: sw a0, 0(a1)430; RV64I-NEXT: ret431;432; RV64ZBB-ZBKB-LABEL: rori_i32_fshr_nosext:433; RV64ZBB-ZBKB: # %bb.0:434; RV64ZBB-ZBKB-NEXT: roriw a0, a0, 31435; RV64ZBB-ZBKB-NEXT: sw a0, 0(a1)436; RV64ZBB-ZBKB-NEXT: ret437 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)438 store i32 %1, ptr %x439 ret void440}441 442; This test is similar to the type legalized version of the fshl/fshr tests, but443; instead of having the same input to both shifts it has different inputs. Make444; sure we don't match it as a roriw.445define signext i32 @not_rori_i32(i32 signext %x, i32 signext %y) nounwind {446; CHECK-LABEL: not_rori_i32:447; CHECK: # %bb.0:448; CHECK-NEXT: slliw a0, a0, 31449; CHECK-NEXT: srliw a1, a1, 1450; CHECK-NEXT: or a0, a0, a1451; CHECK-NEXT: ret452 %a = shl i32 %x, 31453 %b = lshr i32 %y, 1454 %c = or i32 %a, %b455 ret i32 %c456}457 458; This is similar to the type legalized roriw pattern, but the and mask is more459; than 32 bits so the lshr doesn't shift zeroes into the lower 32 bits. Make460; sure we don't match it to roriw.461define i64 @roriw_bug(i64 %x) nounwind {462; CHECK-LABEL: roriw_bug:463; CHECK: # %bb.0:464; CHECK-NEXT: slli a1, a0, 31465; CHECK-NEXT: andi a2, a0, -2466; CHECK-NEXT: srli a0, a0, 1467; CHECK-NEXT: or a0, a1, a0468; CHECK-NEXT: sext.w a0, a0469; CHECK-NEXT: xor a0, a2, a0470; CHECK-NEXT: ret471 %a = shl i64 %x, 31472 %b = and i64 %x, 18446744073709551614473 %c = lshr i64 %b, 1474 %d = or i64 %a, %c475 %e = shl i64 %d, 32476 %f = ashr i64 %e, 32477 %g = xor i64 %b, %f ; to increase the use count on %b to disable SimplifyDemandedBits.478 ret i64 %g479}480 481define i64 @rori_i64_fshl(i64 %a) nounwind {482; RV64I-LABEL: rori_i64_fshl:483; RV64I: # %bb.0:484; RV64I-NEXT: srli a1, a0, 1485; RV64I-NEXT: slli a0, a0, 63486; RV64I-NEXT: or a0, a0, a1487; RV64I-NEXT: ret488;489; RV64ZBB-ZBKB-LABEL: rori_i64_fshl:490; RV64ZBB-ZBKB: # %bb.0:491; RV64ZBB-ZBKB-NEXT: rori a0, a0, 1492; RV64ZBB-ZBKB-NEXT: ret493 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63)494 ret i64 %1495}496 497define i64 @rori_i64_fshr(i64 %a) nounwind {498; RV64I-LABEL: rori_i64_fshr:499; RV64I: # %bb.0:500; RV64I-NEXT: slli a1, a0, 1501; RV64I-NEXT: srli a0, a0, 63502; RV64I-NEXT: or a0, a0, a1503; RV64I-NEXT: ret504;505; RV64ZBB-ZBKB-LABEL: rori_i64_fshr:506; RV64ZBB-ZBKB: # %bb.0:507; RV64ZBB-ZBKB-NEXT: rori a0, a0, 63508; RV64ZBB-ZBKB-NEXT: ret509 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)510 ret i64 %1511}512 513define signext i32 @not_shl_one_i32(i32 signext %x) {514; RV64I-LABEL: not_shl_one_i32:515; RV64I: # %bb.0:516; RV64I-NEXT: li a1, 1517; RV64I-NEXT: sllw a0, a1, a0518; RV64I-NEXT: not a0, a0519; RV64I-NEXT: ret520;521; RV64ZBB-ZBKB-LABEL: not_shl_one_i32:522; RV64ZBB-ZBKB: # %bb.0:523; RV64ZBB-ZBKB-NEXT: li a1, -2524; RV64ZBB-ZBKB-NEXT: rolw a0, a1, a0525; RV64ZBB-ZBKB-NEXT: ret526 %1 = shl i32 1, %x527 %2 = xor i32 %1, -1528 ret i32 %2529}530 531define i64 @not_shl_one_i64(i64 %x) {532; RV64I-LABEL: not_shl_one_i64:533; RV64I: # %bb.0:534; RV64I-NEXT: li a1, 1535; RV64I-NEXT: sll a0, a1, a0536; RV64I-NEXT: not a0, a0537; RV64I-NEXT: ret538;539; RV64ZBB-ZBKB-LABEL: not_shl_one_i64:540; RV64ZBB-ZBKB: # %bb.0:541; RV64ZBB-ZBKB-NEXT: li a1, -2542; RV64ZBB-ZBKB-NEXT: rol a0, a1, a0543; RV64ZBB-ZBKB-NEXT: ret544 %1 = shl i64 1, %x545 %2 = xor i64 %1, -1546 ret i64 %2547}548 549define i8 @srli_i8(i8 %a) nounwind {550; CHECK-LABEL: srli_i8:551; CHECK: # %bb.0:552; CHECK-NEXT: slli a0, a0, 56553; CHECK-NEXT: srli a0, a0, 62554; CHECK-NEXT: ret555 %1 = lshr i8 %a, 6556 ret i8 %1557}558 559; We could use sext.b+srai, but slli+srai offers more opportunities for560; comppressed instructions.561define i8 @srai_i8(i8 %a) nounwind {562; CHECK-LABEL: srai_i8:563; CHECK: # %bb.0:564; CHECK-NEXT: slli a0, a0, 56565; CHECK-NEXT: srai a0, a0, 61566; CHECK-NEXT: ret567 %1 = ashr i8 %a, 5568 ret i8 %1569}570 571; We could use zext.h+srli, but slli+srli offers more opportunities for572; comppressed instructions.573define i16 @srli_i16(i16 %a) nounwind {574; CHECK-LABEL: srli_i16:575; CHECK: # %bb.0:576; CHECK-NEXT: slli a0, a0, 48577; CHECK-NEXT: srli a0, a0, 54578; CHECK-NEXT: ret579 %1 = lshr i16 %a, 6580 ret i16 %1581}582 583; We could use sext.h+srai, but slli+srai offers more opportunities for584; comppressed instructions.585define i16 @srai_i16(i16 %a) nounwind {586; CHECK-LABEL: srai_i16:587; CHECK: # %bb.0:588; CHECK-NEXT: slli a0, a0, 48589; CHECK-NEXT: srai a0, a0, 57590; CHECK-NEXT: ret591 %1 = ashr i16 %a, 9592 ret i16 %1593}594 595define i1 @andn_seqz_i32(i32 signext %a, i32 signext %b) nounwind {596; RV64I-LABEL: andn_seqz_i32:597; RV64I: # %bb.0:598; RV64I-NEXT: and a0, a0, a1599; RV64I-NEXT: xor a0, a0, a1600; RV64I-NEXT: seqz a0, a0601; RV64I-NEXT: ret602;603; RV64ZBB-ZBKB-LABEL: andn_seqz_i32:604; RV64ZBB-ZBKB: # %bb.0:605; RV64ZBB-ZBKB-NEXT: andn a0, a1, a0606; RV64ZBB-ZBKB-NEXT: seqz a0, a0607; RV64ZBB-ZBKB-NEXT: ret608 %and = and i32 %a, %b609 %cmpeq = icmp eq i32 %and, %b610 ret i1 %cmpeq611}612 613define i1 @andn_seqz_i64(i64 %a, i64 %b) nounwind {614; RV64I-LABEL: andn_seqz_i64:615; RV64I: # %bb.0:616; RV64I-NEXT: and a0, a0, a1617; RV64I-NEXT: xor a0, a0, a1618; RV64I-NEXT: seqz a0, a0619; RV64I-NEXT: ret620;621; RV64ZBB-ZBKB-LABEL: andn_seqz_i64:622; RV64ZBB-ZBKB: # %bb.0:623; RV64ZBB-ZBKB-NEXT: andn a0, a1, a0624; RV64ZBB-ZBKB-NEXT: seqz a0, a0625; RV64ZBB-ZBKB-NEXT: ret626 %and = and i64 %a, %b627 %cmpeq = icmp eq i64 %and, %b628 ret i1 %cmpeq629}630 631define i1 @andn_snez_i32(i32 signext %a, i32 signext %b) nounwind {632; RV64I-LABEL: andn_snez_i32:633; RV64I: # %bb.0:634; RV64I-NEXT: and a0, a0, a1635; RV64I-NEXT: xor a0, a0, a1636; RV64I-NEXT: snez a0, a0637; RV64I-NEXT: ret638;639; RV64ZBB-ZBKB-LABEL: andn_snez_i32:640; RV64ZBB-ZBKB: # %bb.0:641; RV64ZBB-ZBKB-NEXT: andn a0, a1, a0642; RV64ZBB-ZBKB-NEXT: snez a0, a0643; RV64ZBB-ZBKB-NEXT: ret644 %and = and i32 %a, %b645 %cmpeq = icmp ne i32 %and, %b646 ret i1 %cmpeq647}648 649define i1 @andn_snez_i64(i64 %a, i64 %b) nounwind {650; RV64I-LABEL: andn_snez_i64:651; RV64I: # %bb.0:652; RV64I-NEXT: and a0, a0, a1653; RV64I-NEXT: xor a0, a0, a1654; RV64I-NEXT: snez a0, a0655; RV64I-NEXT: ret656;657; RV64ZBB-ZBKB-LABEL: andn_snez_i64:658; RV64ZBB-ZBKB: # %bb.0:659; RV64ZBB-ZBKB-NEXT: andn a0, a1, a0660; RV64ZBB-ZBKB-NEXT: snez a0, a0661; RV64ZBB-ZBKB-NEXT: ret662 %and = and i64 %a, %b663 %cmpeq = icmp ne i64 %and, %b664 ret i1 %cmpeq665}666 667define i32 @and_hoisted_not_i32(i32 %x, i32 %m, i1 zeroext %cond) {668; RV64I-LABEL: and_hoisted_not_i32:669; RV64I: # %bb.0:670; RV64I-NEXT: beqz a2, .LBB38_2671; RV64I-NEXT: # %bb.1: # %mask672; RV64I-NEXT: not a1, a1673; RV64I-NEXT: and a0, a1, a0674; RV64I-NEXT: .LBB38_2: # %identity675; RV64I-NEXT: ret676;677; RV64ZBB-ZBKB-LABEL: and_hoisted_not_i32:678; RV64ZBB-ZBKB: # %bb.0:679; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB38_2680; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask681; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1682; RV64ZBB-ZBKB-NEXT: .LBB38_2: # %identity683; RV64ZBB-ZBKB-NEXT: ret684 %a = xor i32 %m, -1685 br i1 %cond, label %mask, label %identity686 687mask:688 %masked = and i32 %a, %x689 ret i32 %masked690 691identity:692 ret i32 %x693}694 695define i32 @and_hoisted_not_i32_swapped(i32 %x, i32 %m, i1 zeroext %cond) {696; RV64I-LABEL: and_hoisted_not_i32_swapped:697; RV64I: # %bb.0:698; RV64I-NEXT: beqz a2, .LBB39_2699; RV64I-NEXT: # %bb.1: # %mask700; RV64I-NEXT: not a1, a1701; RV64I-NEXT: and a0, a0, a1702; RV64I-NEXT: .LBB39_2: # %identity703; RV64I-NEXT: ret704;705; RV64ZBB-ZBKB-LABEL: and_hoisted_not_i32_swapped:706; RV64ZBB-ZBKB: # %bb.0:707; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB39_2708; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask709; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1710; RV64ZBB-ZBKB-NEXT: .LBB39_2: # %identity711; RV64ZBB-ZBKB-NEXT: ret712 %a = xor i32 %m, -1713 br i1 %cond, label %mask, label %identity714 715mask:716 %masked = and i32 %x, %a717 ret i32 %masked718 719identity:720 ret i32 %x721}722 723define i64 @and_hoisted_not_i64(i64 %x, i64 %m, i1 zeroext %cond) {724; RV64I-LABEL: and_hoisted_not_i64:725; RV64I: # %bb.0:726; RV64I-NEXT: beqz a2, .LBB40_2727; RV64I-NEXT: # %bb.1: # %mask728; RV64I-NEXT: not a1, a1729; RV64I-NEXT: and a0, a1, a0730; RV64I-NEXT: .LBB40_2: # %identity731; RV64I-NEXT: ret732;733; RV64ZBB-ZBKB-LABEL: and_hoisted_not_i64:734; RV64ZBB-ZBKB: # %bb.0:735; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB40_2736; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask737; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1738; RV64ZBB-ZBKB-NEXT: .LBB40_2: # %identity739; RV64ZBB-ZBKB-NEXT: ret740 %a = xor i64 %m, -1741 br i1 %cond, label %mask, label %identity742 743mask:744 %masked = and i64 %a, %x745 ret i64 %masked746 747identity:748 ret i64 %x749}750 751define i64 @and_hoisted_not_i64_swapped(i64 %x, i64 %m, i1 zeroext %cond) {752; RV64I-LABEL: and_hoisted_not_i64_swapped:753; RV64I: # %bb.0:754; RV64I-NEXT: beqz a2, .LBB41_2755; RV64I-NEXT: # %bb.1: # %mask756; RV64I-NEXT: not a1, a1757; RV64I-NEXT: and a0, a0, a1758; RV64I-NEXT: .LBB41_2: # %identity759; RV64I-NEXT: ret760;761; RV64ZBB-ZBKB-LABEL: and_hoisted_not_i64_swapped:762; RV64ZBB-ZBKB: # %bb.0:763; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB41_2764; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask765; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1766; RV64ZBB-ZBKB-NEXT: .LBB41_2: # %identity767; RV64ZBB-ZBKB-NEXT: ret768 %a = xor i64 %m, -1769 br i1 %cond, label %mask, label %identity770 771mask:772 %masked = and i64 %x, %a773 ret i64 %masked774 775identity:776 ret i64 %x777}778 779define i32 @or_hoisted_not_i32(i32 %x, i32 %m, i1 zeroext %cond) {780; RV64I-LABEL: or_hoisted_not_i32:781; RV64I: # %bb.0:782; RV64I-NEXT: beqz a2, .LBB42_2783; RV64I-NEXT: # %bb.1: # %mask784; RV64I-NEXT: not a1, a1785; RV64I-NEXT: or a0, a1, a0786; RV64I-NEXT: .LBB42_2: # %identity787; RV64I-NEXT: ret788;789; RV64ZBB-ZBKB-LABEL: or_hoisted_not_i32:790; RV64ZBB-ZBKB: # %bb.0:791; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB42_2792; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask793; RV64ZBB-ZBKB-NEXT: orn a0, a0, a1794; RV64ZBB-ZBKB-NEXT: .LBB42_2: # %identity795; RV64ZBB-ZBKB-NEXT: ret796 %a = xor i32 %m, -1797 br i1 %cond, label %mask, label %identity798 799mask:800 %masked = or i32 %a, %x801 ret i32 %masked802 803identity:804 ret i32 %x805}806 807define i32 @or_hoisted_not_i32_swapped(i32 %x, i32 %m, i1 zeroext %cond) {808; RV64I-LABEL: or_hoisted_not_i32_swapped:809; RV64I: # %bb.0:810; RV64I-NEXT: beqz a2, .LBB43_2811; RV64I-NEXT: # %bb.1: # %mask812; RV64I-NEXT: not a1, a1813; RV64I-NEXT: or a0, a0, a1814; RV64I-NEXT: .LBB43_2: # %identity815; RV64I-NEXT: ret816;817; RV64ZBB-ZBKB-LABEL: or_hoisted_not_i32_swapped:818; RV64ZBB-ZBKB: # %bb.0:819; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB43_2820; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask821; RV64ZBB-ZBKB-NEXT: orn a0, a0, a1822; RV64ZBB-ZBKB-NEXT: .LBB43_2: # %identity823; RV64ZBB-ZBKB-NEXT: ret824 %a = xor i32 %m, -1825 br i1 %cond, label %mask, label %identity826 827mask:828 %masked = or i32 %x, %a829 ret i32 %masked830 831identity:832 ret i32 %x833}834 835define i64 @or_hoisted_not_i64(i64 %x, i64 %m, i1 zeroext %cond) {836; RV64I-LABEL: or_hoisted_not_i64:837; RV64I: # %bb.0:838; RV64I-NEXT: beqz a2, .LBB44_2839; RV64I-NEXT: # %bb.1: # %mask840; RV64I-NEXT: not a1, a1841; RV64I-NEXT: or a0, a1, a0842; RV64I-NEXT: .LBB44_2: # %identity843; RV64I-NEXT: ret844;845; RV64ZBB-ZBKB-LABEL: or_hoisted_not_i64:846; RV64ZBB-ZBKB: # %bb.0:847; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB44_2848; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask849; RV64ZBB-ZBKB-NEXT: orn a0, a0, a1850; RV64ZBB-ZBKB-NEXT: .LBB44_2: # %identity851; RV64ZBB-ZBKB-NEXT: ret852 %a = xor i64 %m, -1853 br i1 %cond, label %mask, label %identity854 855mask:856 %masked = or i64 %a, %x857 ret i64 %masked858 859identity:860 ret i64 %x861}862 863define i64 @or_hoisted_not_i64_swapped(i64 %x, i64 %m, i1 zeroext %cond) {864; RV64I-LABEL: or_hoisted_not_i64_swapped:865; RV64I: # %bb.0:866; RV64I-NEXT: beqz a2, .LBB45_2867; RV64I-NEXT: # %bb.1: # %mask868; RV64I-NEXT: not a1, a1869; RV64I-NEXT: or a0, a0, a1870; RV64I-NEXT: .LBB45_2: # %identity871; RV64I-NEXT: ret872;873; RV64ZBB-ZBKB-LABEL: or_hoisted_not_i64_swapped:874; RV64ZBB-ZBKB: # %bb.0:875; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB45_2876; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask877; RV64ZBB-ZBKB-NEXT: orn a0, a0, a1878; RV64ZBB-ZBKB-NEXT: .LBB45_2: # %identity879; RV64ZBB-ZBKB-NEXT: ret880 %a = xor i64 %m, -1881 br i1 %cond, label %mask, label %identity882 883mask:884 %masked = or i64 %x, %a885 ret i64 %masked886 887identity:888 ret i64 %x889}890 891define i32 @xor_hoisted_not_i32(i32 %x, i32 %m, i1 zeroext %cond) {892; RV64I-LABEL: xor_hoisted_not_i32:893; RV64I: # %bb.0:894; RV64I-NEXT: beqz a2, .LBB46_2895; RV64I-NEXT: # %bb.1: # %mask896; RV64I-NEXT: not a1, a1897; RV64I-NEXT: xor a0, a1, a0898; RV64I-NEXT: .LBB46_2: # %identity899; RV64I-NEXT: ret900;901; RV64ZBB-ZBKB-LABEL: xor_hoisted_not_i32:902; RV64ZBB-ZBKB: # %bb.0:903; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB46_2904; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask905; RV64ZBB-ZBKB-NEXT: xnor a0, a1, a0906; RV64ZBB-ZBKB-NEXT: .LBB46_2: # %identity907; RV64ZBB-ZBKB-NEXT: ret908 %a = xor i32 %m, -1909 br i1 %cond, label %mask, label %identity910 911mask:912 %masked = xor i32 %a, %x913 ret i32 %masked914 915identity:916 ret i32 %x917}918 919define i32 @xor_hoisted_not_i32_swapped(i32 %x, i32 %m, i1 zeroext %cond) {920; RV64I-LABEL: xor_hoisted_not_i32_swapped:921; RV64I: # %bb.0:922; RV64I-NEXT: beqz a2, .LBB47_2923; RV64I-NEXT: # %bb.1: # %mask924; RV64I-NEXT: not a1, a1925; RV64I-NEXT: xor a0, a0, a1926; RV64I-NEXT: .LBB47_2: # %identity927; RV64I-NEXT: ret928;929; RV64ZBB-ZBKB-LABEL: xor_hoisted_not_i32_swapped:930; RV64ZBB-ZBKB: # %bb.0:931; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB47_2932; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask933; RV64ZBB-ZBKB-NEXT: xnor a0, a1, a0934; RV64ZBB-ZBKB-NEXT: .LBB47_2: # %identity935; RV64ZBB-ZBKB-NEXT: ret936 %a = xor i32 %m, -1937 br i1 %cond, label %mask, label %identity938 939mask:940 %masked = xor i32 %x, %a941 ret i32 %masked942 943identity:944 ret i32 %x945}946 947define i64 @xor_hoisted_not_i64(i64 %x, i64 %m, i1 zeroext %cond) {948; RV64I-LABEL: xor_hoisted_not_i64:949; RV64I: # %bb.0:950; RV64I-NEXT: beqz a2, .LBB48_2951; RV64I-NEXT: # %bb.1: # %mask952; RV64I-NEXT: not a1, a1953; RV64I-NEXT: xor a0, a1, a0954; RV64I-NEXT: .LBB48_2: # %identity955; RV64I-NEXT: ret956;957; RV64ZBB-ZBKB-LABEL: xor_hoisted_not_i64:958; RV64ZBB-ZBKB: # %bb.0:959; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB48_2960; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask961; RV64ZBB-ZBKB-NEXT: xnor a0, a1, a0962; RV64ZBB-ZBKB-NEXT: .LBB48_2: # %identity963; RV64ZBB-ZBKB-NEXT: ret964 %a = xor i64 %m, -1965 br i1 %cond, label %mask, label %identity966 967mask:968 %masked = xor i64 %a, %x969 ret i64 %masked970 971identity:972 ret i64 %x973}974 975define i64 @xor_hoisted_not_i64_swapped(i64 %x, i64 %m, i1 zeroext %cond) {976; RV64I-LABEL: xor_hoisted_not_i64_swapped:977; RV64I: # %bb.0:978; RV64I-NEXT: beqz a2, .LBB49_2979; RV64I-NEXT: # %bb.1: # %mask980; RV64I-NEXT: not a1, a1981; RV64I-NEXT: xor a0, a0, a1982; RV64I-NEXT: .LBB49_2: # %identity983; RV64I-NEXT: ret984;985; RV64ZBB-ZBKB-LABEL: xor_hoisted_not_i64_swapped:986; RV64ZBB-ZBKB: # %bb.0:987; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB49_2988; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask989; RV64ZBB-ZBKB-NEXT: xnor a0, a1, a0990; RV64ZBB-ZBKB-NEXT: .LBB49_2: # %identity991; RV64ZBB-ZBKB-NEXT: ret992 %a = xor i64 %m, -1993 br i1 %cond, label %mask, label %identity994 995mask:996 %masked = xor i64 %x, %a997 ret i64 %masked998 999identity:1000 ret i64 %x1001}1002