617 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -mattr=+m -global-isel -verify-machineinstrs < %s \3; RUN: -riscv-enable-copy-propagation=false | FileCheck %s --check-prefix=RV32IM4; RUN: llc -mtriple=riscv64 -mattr=+m -global-isel -verify-machineinstrs < %s \5; RUN: -riscv-enable-copy-propagation=false | FileCheck %s --check-prefix=RV64IM6 7; Extends to 32 bits exhaustively tested for add only.8 9define i8 @add_i8(i8 %a, i8 %b) {10; RV32IM-LABEL: add_i8:11; RV32IM: # %bb.0: # %entry12; RV32IM-NEXT: add a0, a0, a113; RV32IM-NEXT: ret14;15; RV64IM-LABEL: add_i8:16; RV64IM: # %bb.0: # %entry17; RV64IM-NEXT: add a0, a0, a118; RV64IM-NEXT: ret19entry:20 %0 = add i8 %a, %b21 ret i8 %022}23 24define i32 @add_i8_signext_i32(i8 %a, i8 %b) {25; RV32IM-LABEL: add_i8_signext_i32:26; RV32IM: # %bb.0: # %entry27; RV32IM-NEXT: slli a0, a0, 2428; RV32IM-NEXT: slli a1, a1, 2429; RV32IM-NEXT: srai a0, a0, 2430; RV32IM-NEXT: srai a1, a1, 2431; RV32IM-NEXT: add a0, a0, a132; RV32IM-NEXT: ret33;34; RV64IM-LABEL: add_i8_signext_i32:35; RV64IM: # %bb.0: # %entry36; RV64IM-NEXT: slli a0, a0, 5637; RV64IM-NEXT: slli a1, a1, 5638; RV64IM-NEXT: srai a0, a0, 5639; RV64IM-NEXT: srai a1, a1, 5640; RV64IM-NEXT: addw a0, a0, a141; RV64IM-NEXT: ret42entry:43 %0 = sext i8 %a to i3244 %1 = sext i8 %b to i3245 %2 = add i32 %0, %146 ret i32 %247}48 49define i32 @add_i8_zeroext_i32(i8 %a, i8 %b) {50; RV32IM-LABEL: add_i8_zeroext_i32:51; RV32IM: # %bb.0: # %entry52; RV32IM-NEXT: zext.b a0, a053; RV32IM-NEXT: zext.b a1, a154; RV32IM-NEXT: add a0, a0, a155; RV32IM-NEXT: ret56;57; RV64IM-LABEL: add_i8_zeroext_i32:58; RV64IM: # %bb.0: # %entry59; RV64IM-NEXT: zext.b a0, a060; RV64IM-NEXT: zext.b a1, a161; RV64IM-NEXT: addw a0, a0, a162; RV64IM-NEXT: ret63entry:64 %0 = zext i8 %a to i3265 %1 = zext i8 %b to i3266 %2 = add i32 %0, %167 ret i32 %268}69 70; TODO: Handle G_IMPLICIT_DEF, which is needed to have i8 -> i64 extends working71; on RV32.72 73define i32 @add_i32(i32 %a, i32 %b) {74; RV32IM-LABEL: add_i32:75; RV32IM: # %bb.0: # %entry76; RV32IM-NEXT: add a0, a0, a177; RV32IM-NEXT: ret78;79; RV64IM-LABEL: add_i32:80; RV64IM: # %bb.0: # %entry81; RV64IM-NEXT: addw a0, a0, a182; RV64IM-NEXT: ret83entry:84 %0 = add i32 %a, %b85 ret i32 %086}87 88define i32 @addi_i32(i32 %a) {89; RV32IM-LABEL: addi_i32:90; RV32IM: # %bb.0: # %entry91; RV32IM-NEXT: addi a0, a0, 123492; RV32IM-NEXT: ret93;94; RV64IM-LABEL: addi_i32:95; RV64IM: # %bb.0: # %entry96; RV64IM-NEXT: addiw a0, a0, 123497; RV64IM-NEXT: ret98entry:99 %0 = add i32 %a, 1234100 ret i32 %0101}102 103define i32 @sub_i32(i32 %a, i32 %b) {104; RV32IM-LABEL: sub_i32:105; RV32IM: # %bb.0: # %entry106; RV32IM-NEXT: sub a0, a0, a1107; RV32IM-NEXT: ret108;109; RV64IM-LABEL: sub_i32:110; RV64IM: # %bb.0: # %entry111; RV64IM-NEXT: subw a0, a0, a1112; RV64IM-NEXT: ret113entry:114 %0 = sub i32 %a, %b115 ret i32 %0116}117 118define i32 @subi_i32(i32 %a) {119; RV32IM-LABEL: subi_i32:120; RV32IM: # %bb.0: # %entry121; RV32IM-NEXT: addi a0, a0, -1234122; RV32IM-NEXT: ret123;124; RV64IM-LABEL: subi_i32:125; RV64IM: # %bb.0: # %entry126; RV64IM-NEXT: addiw a0, a0, -1234127; RV64IM-NEXT: ret128entry:129 %0 = sub i32 %a, 1234130 ret i32 %0131}132 133define i32 @neg_i32(i32 %a) {134; RV32IM-LABEL: neg_i32:135; RV32IM: # %bb.0: # %entry136; RV32IM-NEXT: neg a0, a0137; RV32IM-NEXT: ret138;139; RV64IM-LABEL: neg_i32:140; RV64IM: # %bb.0: # %entry141; RV64IM-NEXT: negw a0, a0142; RV64IM-NEXT: ret143entry:144 %0 = sub i32 0, %a145 ret i32 %0146}147 148define i32 @sll_i32(i32 %a, i32 %b) {149; RV32IM-LABEL: sll_i32:150; RV32IM: # %bb.0: # %entry151; RV32IM-NEXT: sll a0, a0, a1152; RV32IM-NEXT: ret153;154; RV64IM-LABEL: sll_i32:155; RV64IM: # %bb.0: # %entry156; RV64IM-NEXT: sllw a0, a0, a1157; RV64IM-NEXT: ret158entry:159 %0 = shl i32 %a, %b160 ret i32 %0161}162 163define i32 @slli_i32(i32 %a) {164; RV32IM-LABEL: slli_i32:165; RV32IM: # %bb.0: # %entry166; RV32IM-NEXT: slli a0, a0, 11167; RV32IM-NEXT: ret168;169; RV64IM-LABEL: slli_i32:170; RV64IM: # %bb.0: # %entry171; RV64IM-NEXT: slli a0, a0, 11172; RV64IM-NEXT: ret173entry:174 %0 = shl i32 %a, 11175 ret i32 %0176}177 178define i32 @sra_i32(i32 %a, i32 %b) {179; RV32IM-LABEL: sra_i32:180; RV32IM: # %bb.0: # %entry181; RV32IM-NEXT: sra a0, a0, a1182; RV32IM-NEXT: ret183;184; RV64IM-LABEL: sra_i32:185; RV64IM: # %bb.0: # %entry186; RV64IM-NEXT: sraw a0, a0, a1187; RV64IM-NEXT: ret188entry:189 %0 = ashr i32 %a, %b190 ret i32 %0191}192 193define i32 @srai_i32(i32 %a) {194; RV32IM-LABEL: srai_i32:195; RV32IM: # %bb.0: # %entry196; RV32IM-NEXT: srai a0, a0, 17197; RV32IM-NEXT: ret198;199; RV64IM-LABEL: srai_i32:200; RV64IM: # %bb.0: # %entry201; RV64IM-NEXT: sraiw a0, a0, 17202; RV64IM-NEXT: ret203entry:204 %0 = ashr i32 %a, 17205 ret i32 %0206}207 208define i32 @srl_i32(i32 %a, i32 %b) {209; RV32IM-LABEL: srl_i32:210; RV32IM: # %bb.0: # %entry211; RV32IM-NEXT: srl a0, a0, a1212; RV32IM-NEXT: ret213;214; RV64IM-LABEL: srl_i32:215; RV64IM: # %bb.0: # %entry216; RV64IM-NEXT: srlw a0, a0, a1217; RV64IM-NEXT: ret218entry:219 %0 = lshr i32 %a, %b220 ret i32 %0221}222 223define i32 @srli_i32(i32 %a, i32 %b) {224; RV32IM-LABEL: srli_i32:225; RV32IM: # %bb.0: # %entry226; RV32IM-NEXT: srli a0, a0, 23227; RV32IM-NEXT: ret228;229; RV64IM-LABEL: srli_i32:230; RV64IM: # %bb.0: # %entry231; RV64IM-NEXT: srliw a0, a0, 23232; RV64IM-NEXT: ret233entry:234 %0 = lshr i32 %a, 23235 ret i32 %0236}237 238define i32 @and_i32(i32 %a, i32 %b) {239; RV32IM-LABEL: and_i32:240; RV32IM: # %bb.0: # %entry241; RV32IM-NEXT: and a0, a0, a1242; RV32IM-NEXT: ret243;244; RV64IM-LABEL: and_i32:245; RV64IM: # %bb.0: # %entry246; RV64IM-NEXT: and a0, a0, a1247; RV64IM-NEXT: ret248entry:249 %0 = and i32 %a, %b250 ret i32 %0251}252 253define i32 @andi_i32(i32 %a) {254; RV32IM-LABEL: andi_i32:255; RV32IM: # %bb.0: # %entry256; RV32IM-NEXT: andi a0, a0, 1234257; RV32IM-NEXT: ret258;259; RV64IM-LABEL: andi_i32:260; RV64IM: # %bb.0: # %entry261; RV64IM-NEXT: andi a0, a0, 1234262; RV64IM-NEXT: ret263entry:264 %0 = and i32 %a, 1234265 ret i32 %0266}267 268define i32 @or_i32(i32 %a, i32 %b) {269; RV32IM-LABEL: or_i32:270; RV32IM: # %bb.0: # %entry271; RV32IM-NEXT: or a0, a0, a1272; RV32IM-NEXT: ret273;274; RV64IM-LABEL: or_i32:275; RV64IM: # %bb.0: # %entry276; RV64IM-NEXT: or a0, a0, a1277; RV64IM-NEXT: ret278entry:279 %0 = or i32 %a, %b280 ret i32 %0281}282 283define i32 @ori_i32(i32 %a) {284; RV32IM-LABEL: ori_i32:285; RV32IM: # %bb.0: # %entry286; RV32IM-NEXT: ori a0, a0, 1234287; RV32IM-NEXT: ret288;289; RV64IM-LABEL: ori_i32:290; RV64IM: # %bb.0: # %entry291; RV64IM-NEXT: ori a0, a0, 1234292; RV64IM-NEXT: ret293entry:294 %0 = or i32 %a, 1234295 ret i32 %0296}297 298define i32 @xor_i32(i32 %a, i32 %b) {299; RV32IM-LABEL: xor_i32:300; RV32IM: # %bb.0: # %entry301; RV32IM-NEXT: xor a0, a0, a1302; RV32IM-NEXT: ret303;304; RV64IM-LABEL: xor_i32:305; RV64IM: # %bb.0: # %entry306; RV64IM-NEXT: xor a0, a0, a1307; RV64IM-NEXT: ret308entry:309 %0 = xor i32 %a, %b310 ret i32 %0311}312 313define i32 @xori_i32(i32 %a, i32 %b) {314; RV32IM-LABEL: xori_i32:315; RV32IM: # %bb.0: # %entry316; RV32IM-NEXT: xori a0, a0, 1234317; RV32IM-NEXT: ret318;319; RV64IM-LABEL: xori_i32:320; RV64IM: # %bb.0: # %entry321; RV64IM-NEXT: xori a0, a0, 1234322; RV64IM-NEXT: ret323entry:324 %0 = xor i32 %a, 1234325 ret i32 %0326}327 328define i32 @mul_i32(i32 %a, i32 %b) {329; RV32IM-LABEL: mul_i32:330; RV32IM: # %bb.0: # %entry331; RV32IM-NEXT: mul a0, a0, a1332; RV32IM-NEXT: ret333;334; RV64IM-LABEL: mul_i32:335; RV64IM: # %bb.0: # %entry336; RV64IM-NEXT: mul a0, a0, a1337; RV64IM-NEXT: ret338entry:339 %0 = mul i32 %a, %b340 ret i32 %0341}342 343define i32 @sdiv_i32(i32 %a, i32 %b) {344; RV32IM-LABEL: sdiv_i32:345; RV32IM: # %bb.0: # %entry346; RV32IM-NEXT: div a0, a0, a1347; RV32IM-NEXT: ret348;349; RV64IM-LABEL: sdiv_i32:350; RV64IM: # %bb.0: # %entry351; RV64IM-NEXT: divw a0, a0, a1352; RV64IM-NEXT: ret353entry:354 %0 = sdiv i32 %a, %b355 ret i32 %0356}357 358define i32 @srem_i32(i32 %a, i32 %b) {359; RV32IM-LABEL: srem_i32:360; RV32IM: # %bb.0: # %entry361; RV32IM-NEXT: rem a0, a0, a1362; RV32IM-NEXT: ret363;364; RV64IM-LABEL: srem_i32:365; RV64IM: # %bb.0: # %entry366; RV64IM-NEXT: remw a0, a0, a1367; RV64IM-NEXT: ret368entry:369 %0 = srem i32 %a, %b370 ret i32 %0371}372 373define i32 @udiv_i32(i32 %a, i32 %b) {374; RV32IM-LABEL: udiv_i32:375; RV32IM: # %bb.0: # %entry376; RV32IM-NEXT: divu a0, a0, a1377; RV32IM-NEXT: ret378;379; RV64IM-LABEL: udiv_i32:380; RV64IM: # %bb.0: # %entry381; RV64IM-NEXT: divuw a0, a0, a1382; RV64IM-NEXT: ret383entry:384 %0 = udiv i32 %a, %b385 ret i32 %0386}387 388define i32 @urem_i32(i32 %a, i32 %b) {389; RV32IM-LABEL: urem_i32:390; RV32IM: # %bb.0: # %entry391; RV32IM-NEXT: remu a0, a0, a1392; RV32IM-NEXT: ret393;394; RV64IM-LABEL: urem_i32:395; RV64IM: # %bb.0: # %entry396; RV64IM-NEXT: remuw a0, a0, a1397; RV64IM-NEXT: ret398entry:399 %0 = urem i32 %a, %b400 ret i32 %0401}402 403define i64 @add_i64(i64 %a, i64 %b) {404; RV32IM-LABEL: add_i64:405; RV32IM: # %bb.0: # %entry406; RV32IM-NEXT: add a0, a0, a2407; RV32IM-NEXT: sltu a2, a0, a2408; RV32IM-NEXT: add a1, a1, a3409; RV32IM-NEXT: add a1, a1, a2410; RV32IM-NEXT: ret411;412; RV64IM-LABEL: add_i64:413; RV64IM: # %bb.0: # %entry414; RV64IM-NEXT: add a0, a0, a1415; RV64IM-NEXT: ret416entry:417 %0 = add i64 %a, %b418 ret i64 %0419}420 421define i64 @addi_i64(i64 %a) {422; RV32IM-LABEL: addi_i64:423; RV32IM: # %bb.0: # %entry424; RV32IM-NEXT: addi a0, a0, 1234425; RV32IM-NEXT: sltiu a2, a0, 1234426; RV32IM-NEXT: add a1, a1, a2427; RV32IM-NEXT: ret428;429; RV64IM-LABEL: addi_i64:430; RV64IM: # %bb.0: # %entry431; RV64IM-NEXT: addi a0, a0, 1234432; RV64IM-NEXT: ret433entry:434 %0 = add i64 %a, 1234435 ret i64 %0436}437 438define i64 @sub_i64(i64 %a, i64 %b) {439; RV32IM-LABEL: sub_i64:440; RV32IM: # %bb.0: # %entry441; RV32IM-NEXT: sub a4, a0, a2442; RV32IM-NEXT: sltu a0, a0, a2443; RV32IM-NEXT: sub a1, a1, a3444; RV32IM-NEXT: sub a1, a1, a0445; RV32IM-NEXT: mv a0, a4446; RV32IM-NEXT: ret447;448; RV64IM-LABEL: sub_i64:449; RV64IM: # %bb.0: # %entry450; RV64IM-NEXT: sub a0, a0, a1451; RV64IM-NEXT: ret452entry:453 %0 = sub i64 %a, %b454 ret i64 %0455}456 457define i64 @subi_i64(i64 %a) {458; RV32IM-LABEL: subi_i64:459; RV32IM: # %bb.0: # %entry460; RV32IM-NEXT: lui a2, 1048275461; RV32IM-NEXT: addi a2, a2, -1548462; RV32IM-NEXT: add a0, a0, a2463; RV32IM-NEXT: sltu a2, a0, a2464; RV32IM-NEXT: addi a1, a1, -1465; RV32IM-NEXT: add a1, a1, a2466; RV32IM-NEXT: ret467;468; RV64IM-LABEL: subi_i64:469; RV64IM: # %bb.0: # %entry470; RV64IM-NEXT: lui a1, 1048275471; RV64IM-NEXT: addi a1, a1, -1548472; RV64IM-NEXT: add a0, a0, a1473; RV64IM-NEXT: ret474entry:475 %0 = sub i64 %a, 1234444476 ret i64 %0477}478 479define i64 @neg_i64(i64 %a) {480; RV32IM-LABEL: neg_i64:481; RV32IM: # %bb.0: # %entry482; RV32IM-NEXT: neg a2, a0483; RV32IM-NEXT: snez a0, a0484; RV32IM-NEXT: neg a1, a1485; RV32IM-NEXT: sub a1, a1, a0486; RV32IM-NEXT: mv a0, a2487; RV32IM-NEXT: ret488;489; RV64IM-LABEL: neg_i64:490; RV64IM: # %bb.0: # %entry491; RV64IM-NEXT: neg a0, a0492; RV64IM-NEXT: ret493entry:494 %0 = sub i64 0, %a495 ret i64 %0496}497 498; TODO: Handle G_SELECT, which is needed to have i64 shifts working on RV32.499 500define i64 @and_i64(i64 %a, i64 %b) {501; RV32IM-LABEL: and_i64:502; RV32IM: # %bb.0: # %entry503; RV32IM-NEXT: and a0, a0, a2504; RV32IM-NEXT: and a1, a1, a3505; RV32IM-NEXT: ret506;507; RV64IM-LABEL: and_i64:508; RV64IM: # %bb.0: # %entry509; RV64IM-NEXT: and a0, a0, a1510; RV64IM-NEXT: ret511entry:512 %0 = and i64 %a, %b513 ret i64 %0514}515 516define i64 @andi_i64(i64 %a) {517; RV32IM-LABEL: andi_i64:518; RV32IM: # %bb.0: # %entry519; RV32IM-NEXT: andi a0, a0, 1234520; RV32IM-NEXT: li a1, 0521; RV32IM-NEXT: ret522;523; RV64IM-LABEL: andi_i64:524; RV64IM: # %bb.0: # %entry525; RV64IM-NEXT: andi a0, a0, 1234526; RV64IM-NEXT: ret527entry:528 %0 = and i64 %a, 1234529 ret i64 %0530}531 532define i64 @or_i64(i64 %a, i64 %b) {533; RV32IM-LABEL: or_i64:534; RV32IM: # %bb.0: # %entry535; RV32IM-NEXT: or a0, a0, a2536; RV32IM-NEXT: or a1, a1, a3537; RV32IM-NEXT: ret538;539; RV64IM-LABEL: or_i64:540; RV64IM: # %bb.0: # %entry541; RV64IM-NEXT: or a0, a0, a1542; RV64IM-NEXT: ret543entry:544 %0 = or i64 %a, %b545 ret i64 %0546}547 548define i64 @ori_i64(i64 %a) {549; RV32IM-LABEL: ori_i64:550; RV32IM: # %bb.0: # %entry551; RV32IM-NEXT: ori a0, a0, 1234552; RV32IM-NEXT: ret553;554; RV64IM-LABEL: ori_i64:555; RV64IM: # %bb.0: # %entry556; RV64IM-NEXT: ori a0, a0, 1234557; RV64IM-NEXT: ret558entry:559 %0 = or i64 %a, 1234560 ret i64 %0561}562 563define i64 @xor_i64(i64 %a, i64 %b) {564; RV32IM-LABEL: xor_i64:565; RV32IM: # %bb.0: # %entry566; RV32IM-NEXT: xor a0, a0, a2567; RV32IM-NEXT: xor a1, a1, a3568; RV32IM-NEXT: ret569;570; RV64IM-LABEL: xor_i64:571; RV64IM: # %bb.0: # %entry572; RV64IM-NEXT: xor a0, a0, a1573; RV64IM-NEXT: ret574entry:575 %0 = xor i64 %a, %b576 ret i64 %0577}578 579define i64 @xori_i64(i64 %a) {580; RV32IM-LABEL: xori_i64:581; RV32IM: # %bb.0: # %entry582; RV32IM-NEXT: xori a0, a0, 1234583; RV32IM-NEXT: ret584;585; RV64IM-LABEL: xori_i64:586; RV64IM: # %bb.0: # %entry587; RV64IM-NEXT: xori a0, a0, 1234588; RV64IM-NEXT: ret589entry:590 %0 = xor i64 %a, 1234591 ret i64 %0592}593 594define i64 @mul_i64(i64 %a, i64 %b) {595; RV32IM-LABEL: mul_i64:596; RV32IM: # %bb.0: # %entry597; RV32IM-NEXT: mul a4, a0, a2598; RV32IM-NEXT: mul a1, a1, a2599; RV32IM-NEXT: mul a3, a0, a3600; RV32IM-NEXT: mulhu a0, a0, a2601; RV32IM-NEXT: add a1, a1, a3602; RV32IM-NEXT: add a1, a1, a0603; RV32IM-NEXT: mv a0, a4604; RV32IM-NEXT: ret605;606; RV64IM-LABEL: mul_i64:607; RV64IM: # %bb.0: # %entry608; RV64IM-NEXT: mul a0, a0, a1609; RV64IM-NEXT: ret610entry:611 %0 = mul i64 %a, %b612 ret i64 %0613}614 615; TODO: Handle G_SDIV, G_SREM, G_UDIV, G_UREM for i64 on RV32. Likely will be616; dispatched to a libcall?617