604 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-prefix=RV64I4; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \5; RUN: | FileCheck %s -check-prefix=RV32I6 7; These tests are each targeted at a particular RISC-V ALU instruction. Other8; files in this folder exercise LLVM IR instructions that don't directly match a9; RISC-V instruction. This file contains tests for the instructions common10; between RV32I and RV64I as well as the *W instructions introduced in RV64I.11 12; Register-immediate instructions13 14define i64 @addi(i64 %a) nounwind {15; RV64I-LABEL: addi:16; RV64I: # %bb.0:17; RV64I-NEXT: addi a0, a0, 118; RV64I-NEXT: ret19;20; RV32I-LABEL: addi:21; RV32I: # %bb.0:22; RV32I-NEXT: addi a0, a0, 123; RV32I-NEXT: seqz a2, a024; RV32I-NEXT: add a1, a1, a225; RV32I-NEXT: ret26 %1 = add i64 %a, 127 ret i64 %128}29 30define i64 @slti(i64 %a) nounwind {31; RV64I-LABEL: slti:32; RV64I: # %bb.0:33; RV64I-NEXT: slti a0, a0, 234; RV64I-NEXT: ret35;36; RV32I-LABEL: slti:37; RV32I: # %bb.0:38; RV32I-NEXT: beqz a1, .LBB1_239; RV32I-NEXT: # %bb.1:40; RV32I-NEXT: srli a0, a1, 3141; RV32I-NEXT: li a1, 042; RV32I-NEXT: ret43; RV32I-NEXT: .LBB1_2:44; RV32I-NEXT: sltiu a0, a0, 245; RV32I-NEXT: li a1, 046; RV32I-NEXT: ret47 %1 = icmp slt i64 %a, 248 %2 = zext i1 %1 to i6449 ret i64 %250}51 52define i64 @sltiu(i64 %a) nounwind {53; RV64I-LABEL: sltiu:54; RV64I: # %bb.0:55; RV64I-NEXT: sltiu a0, a0, 356; RV64I-NEXT: ret57;58; RV32I-LABEL: sltiu:59; RV32I: # %bb.0:60; RV32I-NEXT: sltiu a0, a0, 361; RV32I-NEXT: seqz a1, a162; RV32I-NEXT: and a0, a1, a063; RV32I-NEXT: li a1, 064; RV32I-NEXT: ret65 %1 = icmp ult i64 %a, 366 %2 = zext i1 %1 to i6467 ret i64 %268}69 70define i64 @xori(i64 %a) nounwind {71; RV64I-LABEL: xori:72; RV64I: # %bb.0:73; RV64I-NEXT: xori a0, a0, 474; RV64I-NEXT: ret75;76; RV32I-LABEL: xori:77; RV32I: # %bb.0:78; RV32I-NEXT: xori a0, a0, 479; RV32I-NEXT: ret80 %1 = xor i64 %a, 481 ret i64 %182}83 84define i64 @ori(i64 %a) nounwind {85; RV64I-LABEL: ori:86; RV64I: # %bb.0:87; RV64I-NEXT: ori a0, a0, 588; RV64I-NEXT: ret89;90; RV32I-LABEL: ori:91; RV32I: # %bb.0:92; RV32I-NEXT: ori a0, a0, 593; RV32I-NEXT: ret94 %1 = or i64 %a, 595 ret i64 %196}97 98define i64 @andi(i64 %a) nounwind {99; RV64I-LABEL: andi:100; RV64I: # %bb.0:101; RV64I-NEXT: andi a0, a0, 6102; RV64I-NEXT: ret103;104; RV32I-LABEL: andi:105; RV32I: # %bb.0:106; RV32I-NEXT: andi a0, a0, 6107; RV32I-NEXT: li a1, 0108; RV32I-NEXT: ret109 %1 = and i64 %a, 6110 ret i64 %1111}112 113define i64 @slli(i64 %a) nounwind {114; RV64I-LABEL: slli:115; RV64I: # %bb.0:116; RV64I-NEXT: slli a0, a0, 7117; RV64I-NEXT: ret118;119; RV32I-LABEL: slli:120; RV32I: # %bb.0:121; RV32I-NEXT: srli a2, a0, 25122; RV32I-NEXT: slli a1, a1, 7123; RV32I-NEXT: or a1, a1, a2124; RV32I-NEXT: slli a0, a0, 7125; RV32I-NEXT: ret126 %1 = shl i64 %a, 7127 ret i64 %1128}129 130define i64 @srli(i64 %a) nounwind {131; RV64I-LABEL: srli:132; RV64I: # %bb.0:133; RV64I-NEXT: srli a0, a0, 8134; RV64I-NEXT: ret135;136; RV32I-LABEL: srli:137; RV32I: # %bb.0:138; RV32I-NEXT: slli a2, a1, 24139; RV32I-NEXT: srli a0, a0, 8140; RV32I-NEXT: or a0, a0, a2141; RV32I-NEXT: srli a1, a1, 8142; RV32I-NEXT: ret143 %1 = lshr i64 %a, 8144 ret i64 %1145}146 147define i64 @srai(i64 %a) nounwind {148; RV64I-LABEL: srai:149; RV64I: # %bb.0:150; RV64I-NEXT: srai a0, a0, 9151; RV64I-NEXT: ret152;153; RV32I-LABEL: srai:154; RV32I: # %bb.0:155; RV32I-NEXT: slli a2, a1, 23156; RV32I-NEXT: srli a0, a0, 9157; RV32I-NEXT: or a0, a0, a2158; RV32I-NEXT: srai a1, a1, 9159; RV32I-NEXT: ret160 %1 = ashr i64 %a, 9161 ret i64 %1162}163 164; Register-register instructions165 166define i64 @add(i64 %a, i64 %b) nounwind {167; RV64I-LABEL: add:168; RV64I: # %bb.0:169; RV64I-NEXT: add a0, a0, a1170; RV64I-NEXT: ret171;172; RV32I-LABEL: add:173; RV32I: # %bb.0:174; RV32I-NEXT: add a1, a1, a3175; RV32I-NEXT: add a2, a0, a2176; RV32I-NEXT: sltu a0, a2, a0177; RV32I-NEXT: add a1, a1, a0178; RV32I-NEXT: mv a0, a2179; RV32I-NEXT: ret180 %1 = add i64 %a, %b181 ret i64 %1182}183 184define i64 @sub(i64 %a, i64 %b) nounwind {185; RV64I-LABEL: sub:186; RV64I: # %bb.0:187; RV64I-NEXT: sub a0, a0, a1188; RV64I-NEXT: ret189;190; RV32I-LABEL: sub:191; RV32I: # %bb.0:192; RV32I-NEXT: sltu a4, a0, a2193; RV32I-NEXT: sub a1, a1, a3194; RV32I-NEXT: sub a1, a1, a4195; RV32I-NEXT: sub a0, a0, a2196; RV32I-NEXT: ret197 %1 = sub i64 %a, %b198 ret i64 %1199}200 201define i64 @sll(i64 %a, i64 %b) nounwind {202; RV64I-LABEL: sll:203; RV64I: # %bb.0:204; RV64I-NEXT: sll a0, a0, a1205; RV64I-NEXT: ret206;207; RV32I-LABEL: sll:208; RV32I: # %bb.0:209; RV32I-NEXT: addi a4, a2, -32210; RV32I-NEXT: sll a3, a0, a2211; RV32I-NEXT: bltz a4, .LBB11_2212; RV32I-NEXT: # %bb.1:213; RV32I-NEXT: mv a1, a3214; RV32I-NEXT: j .LBB11_3215; RV32I-NEXT: .LBB11_2:216; RV32I-NEXT: sll a1, a1, a2217; RV32I-NEXT: not a2, a2218; RV32I-NEXT: srli a0, a0, 1219; RV32I-NEXT: srl a0, a0, a2220; RV32I-NEXT: or a1, a1, a0221; RV32I-NEXT: .LBB11_3:222; RV32I-NEXT: srai a0, a4, 31223; RV32I-NEXT: and a0, a0, a3224; RV32I-NEXT: ret225 %1 = shl i64 %a, %b226 ret i64 %1227}228 229define i64 @slt(i64 %a, i64 %b) nounwind {230; RV64I-LABEL: slt:231; RV64I: # %bb.0:232; RV64I-NEXT: slt a0, a0, a1233; RV64I-NEXT: ret234;235; RV32I-LABEL: slt:236; RV32I: # %bb.0:237; RV32I-NEXT: beq a1, a3, .LBB12_2238; RV32I-NEXT: # %bb.1:239; RV32I-NEXT: slt a0, a1, a3240; RV32I-NEXT: li a1, 0241; RV32I-NEXT: ret242; RV32I-NEXT: .LBB12_2:243; RV32I-NEXT: sltu a0, a0, a2244; RV32I-NEXT: li a1, 0245; RV32I-NEXT: ret246 %1 = icmp slt i64 %a, %b247 %2 = zext i1 %1 to i64248 ret i64 %2249}250 251define i64 @sltu(i64 %a, i64 %b) nounwind {252; RV64I-LABEL: sltu:253; RV64I: # %bb.0:254; RV64I-NEXT: sltu a0, a0, a1255; RV64I-NEXT: ret256;257; RV32I-LABEL: sltu:258; RV32I: # %bb.0:259; RV32I-NEXT: beq a1, a3, .LBB13_2260; RV32I-NEXT: # %bb.1:261; RV32I-NEXT: sltu a0, a1, a3262; RV32I-NEXT: li a1, 0263; RV32I-NEXT: ret264; RV32I-NEXT: .LBB13_2:265; RV32I-NEXT: sltu a0, a0, a2266; RV32I-NEXT: li a1, 0267; RV32I-NEXT: ret268 %1 = icmp ult i64 %a, %b269 %2 = zext i1 %1 to i64270 ret i64 %2271}272 273define i64 @xor(i64 %a, i64 %b) nounwind {274; RV64I-LABEL: xor:275; RV64I: # %bb.0:276; RV64I-NEXT: xor a0, a0, a1277; RV64I-NEXT: ret278;279; RV32I-LABEL: xor:280; RV32I: # %bb.0:281; RV32I-NEXT: xor a0, a0, a2282; RV32I-NEXT: xor a1, a1, a3283; RV32I-NEXT: ret284 %1 = xor i64 %a, %b285 ret i64 %1286}287 288define i64 @srl(i64 %a, i64 %b) nounwind {289; RV64I-LABEL: srl:290; RV64I: # %bb.0:291; RV64I-NEXT: srl a0, a0, a1292; RV64I-NEXT: ret293;294; RV32I-LABEL: srl:295; RV32I: # %bb.0:296; RV32I-NEXT: addi a4, a2, -32297; RV32I-NEXT: srl a3, a1, a2298; RV32I-NEXT: bltz a4, .LBB15_2299; RV32I-NEXT: # %bb.1:300; RV32I-NEXT: mv a0, a3301; RV32I-NEXT: j .LBB15_3302; RV32I-NEXT: .LBB15_2:303; RV32I-NEXT: srl a0, a0, a2304; RV32I-NEXT: not a2, a2305; RV32I-NEXT: slli a1, a1, 1306; RV32I-NEXT: sll a1, a1, a2307; RV32I-NEXT: or a0, a0, a1308; RV32I-NEXT: .LBB15_3:309; RV32I-NEXT: srai a1, a4, 31310; RV32I-NEXT: and a1, a1, a3311; RV32I-NEXT: ret312 %1 = lshr i64 %a, %b313 ret i64 %1314}315 316define i64 @sra(i64 %a, i64 %b) nounwind {317; RV64I-LABEL: sra:318; RV64I: # %bb.0:319; RV64I-NEXT: sra a0, a0, a1320; RV64I-NEXT: ret321;322; RV32I-LABEL: sra:323; RV32I: # %bb.0:324; RV32I-NEXT: mv a3, a1325; RV32I-NEXT: addi a4, a2, -32326; RV32I-NEXT: sra a1, a1, a2327; RV32I-NEXT: bltz a4, .LBB16_2328; RV32I-NEXT: # %bb.1:329; RV32I-NEXT: srai a3, a3, 31330; RV32I-NEXT: mv a0, a1331; RV32I-NEXT: mv a1, a3332; RV32I-NEXT: ret333; RV32I-NEXT: .LBB16_2:334; RV32I-NEXT: srl a0, a0, a2335; RV32I-NEXT: not a2, a2336; RV32I-NEXT: slli a3, a3, 1337; RV32I-NEXT: sll a2, a3, a2338; RV32I-NEXT: or a0, a0, a2339; RV32I-NEXT: ret340 %1 = ashr i64 %a, %b341 ret i64 %1342}343 344define i64 @or(i64 %a, i64 %b) nounwind {345; RV64I-LABEL: or:346; RV64I: # %bb.0:347; RV64I-NEXT: or a0, a0, a1348; RV64I-NEXT: ret349;350; RV32I-LABEL: or:351; RV32I: # %bb.0:352; RV32I-NEXT: or a0, a0, a2353; RV32I-NEXT: or a1, a1, a3354; RV32I-NEXT: ret355 %1 = or i64 %a, %b356 ret i64 %1357}358 359define i64 @and(i64 %a, i64 %b) nounwind {360; RV64I-LABEL: and:361; RV64I: # %bb.0:362; RV64I-NEXT: and a0, a0, a1363; RV64I-NEXT: ret364;365; RV32I-LABEL: and:366; RV32I: # %bb.0:367; RV32I-NEXT: and a0, a0, a2368; RV32I-NEXT: and a1, a1, a3369; RV32I-NEXT: ret370 %1 = and i64 %a, %b371 ret i64 %1372}373 374; RV64I-only instructions375 376define signext i32 @addiw(i32 signext %a) nounwind {377; RV64I-LABEL: addiw:378; RV64I: # %bb.0:379; RV64I-NEXT: addiw a0, a0, 123380; RV64I-NEXT: ret381;382; RV32I-LABEL: addiw:383; RV32I: # %bb.0:384; RV32I-NEXT: addi a0, a0, 123385; RV32I-NEXT: ret386 %1 = add i32 %a, 123387 ret i32 %1388}389 390define signext i32 @slliw(i32 signext %a) nounwind {391; RV64I-LABEL: slliw:392; RV64I: # %bb.0:393; RV64I-NEXT: slliw a0, a0, 17394; RV64I-NEXT: ret395;396; RV32I-LABEL: slliw:397; RV32I: # %bb.0:398; RV32I-NEXT: slli a0, a0, 17399; RV32I-NEXT: ret400 %1 = shl i32 %a, 17401 ret i32 %1402}403 404define signext i32 @srliw(i32 %a) nounwind {405; RV64I-LABEL: srliw:406; RV64I: # %bb.0:407; RV64I-NEXT: srliw a0, a0, 8408; RV64I-NEXT: ret409;410; RV32I-LABEL: srliw:411; RV32I: # %bb.0:412; RV32I-NEXT: srli a0, a0, 8413; RV32I-NEXT: ret414 %1 = lshr i32 %a, 8415 ret i32 %1416}417 418define signext i32 @sraiw(i32 %a) nounwind {419; RV64I-LABEL: sraiw:420; RV64I: # %bb.0:421; RV64I-NEXT: sraiw a0, a0, 9422; RV64I-NEXT: ret423;424; RV32I-LABEL: sraiw:425; RV32I: # %bb.0:426; RV32I-NEXT: srai a0, a0, 9427; RV32I-NEXT: ret428 %1 = ashr i32 %a, 9429 ret i32 %1430}431 432define i64 @sraiw_i64(i64 %a) nounwind {433; RV64I-LABEL: sraiw_i64:434; RV64I: # %bb.0:435; RV64I-NEXT: sraiw a0, a0, 9436; RV64I-NEXT: ret437;438; RV32I-LABEL: sraiw_i64:439; RV32I: # %bb.0:440; RV32I-NEXT: srai a2, a0, 9441; RV32I-NEXT: srai a1, a0, 31442; RV32I-NEXT: mv a0, a2443; RV32I-NEXT: ret444 %1 = shl i64 %a, 32445 %2 = ashr i64 %1, 41446 ret i64 %2447}448 449define signext i32 @sextw(i32 zeroext %a) nounwind {450; RV64I-LABEL: sextw:451; RV64I: # %bb.0:452; RV64I-NEXT: sext.w a0, a0453; RV64I-NEXT: ret454;455; RV32I-LABEL: sextw:456; RV32I: # %bb.0:457; RV32I-NEXT: ret458 ret i32 %a459}460 461define signext i32 @addw(i32 signext %a, i32 signext %b) nounwind {462; RV64I-LABEL: addw:463; RV64I: # %bb.0:464; RV64I-NEXT: addw a0, a0, a1465; RV64I-NEXT: ret466;467; RV32I-LABEL: addw:468; RV32I: # %bb.0:469; RV32I-NEXT: add a0, a0, a1470; RV32I-NEXT: ret471 %1 = add i32 %a, %b472 ret i32 %1473}474 475define signext i32 @subw(i32 signext %a, i32 signext %b) nounwind {476; RV64I-LABEL: subw:477; RV64I: # %bb.0:478; RV64I-NEXT: subw a0, a0, a1479; RV64I-NEXT: ret480;481; RV32I-LABEL: subw:482; RV32I: # %bb.0:483; RV32I-NEXT: sub a0, a0, a1484; RV32I-NEXT: ret485 %1 = sub i32 %a, %b486 ret i32 %1487}488 489define signext i32 @sllw(i32 signext %a, i32 zeroext %b) nounwind {490; RV64I-LABEL: sllw:491; RV64I: # %bb.0:492; RV64I-NEXT: sllw a0, a0, a1493; RV64I-NEXT: ret494;495; RV32I-LABEL: sllw:496; RV32I: # %bb.0:497; RV32I-NEXT: sll a0, a0, a1498; RV32I-NEXT: ret499 %1 = shl i32 %a, %b500 ret i32 %1501}502 503define signext i32 @srlw(i32 signext %a, i32 zeroext %b) nounwind {504; RV64I-LABEL: srlw:505; RV64I: # %bb.0:506; RV64I-NEXT: srlw a0, a0, a1507; RV64I-NEXT: ret508;509; RV32I-LABEL: srlw:510; RV32I: # %bb.0:511; RV32I-NEXT: srl a0, a0, a1512; RV32I-NEXT: ret513 %1 = lshr i32 %a, %b514 ret i32 %1515}516 517define signext i32 @sraw(i64 %a, i32 zeroext %b) nounwind {518; RV64I-LABEL: sraw:519; RV64I: # %bb.0:520; RV64I-NEXT: sraw a0, a0, a1521; RV64I-NEXT: ret522;523; RV32I-LABEL: sraw:524; RV32I: # %bb.0:525; RV32I-NEXT: sra a0, a0, a2526; RV32I-NEXT: ret527 %1 = trunc i64 %a to i32528 %2 = ashr i32 %1, %b529 ret i32 %2530}531 532define i64 @add_hi_and_lo_negone(i64 %0) {533; RV64I-LABEL: add_hi_and_lo_negone:534; RV64I: # %bb.0:535; RV64I-NEXT: addi a0, a0, -1536; RV64I-NEXT: ret537;538; RV32I-LABEL: add_hi_and_lo_negone:539; RV32I: # %bb.0:540; RV32I-NEXT: seqz a2, a0541; RV32I-NEXT: sub a1, a1, a2542; RV32I-NEXT: addi a0, a0, -1543; RV32I-NEXT: ret544 %2 = add nsw i64 %0, -1545 ret i64 %2546}547 548define i64 @add_hi_zero_lo_negone(i64 %0) {549; RV64I-LABEL: add_hi_zero_lo_negone:550; RV64I: # %bb.0:551; RV64I-NEXT: li a1, -1552; RV64I-NEXT: srli a1, a1, 32553; RV64I-NEXT: add a0, a0, a1554; RV64I-NEXT: ret555;556; RV32I-LABEL: add_hi_zero_lo_negone:557; RV32I: # %bb.0:558; RV32I-NEXT: snez a2, a0559; RV32I-NEXT: add a1, a1, a2560; RV32I-NEXT: addi a0, a0, -1561; RV32I-NEXT: ret562 %2 = add i64 %0, 4294967295563 ret i64 %2564}565 566define i64 @add_lo_negone(i64 %0) {567; RV64I-LABEL: add_lo_negone:568; RV64I: # %bb.0:569; RV64I-NEXT: li a1, -1570; RV64I-NEXT: slli a1, a1, 32571; RV64I-NEXT: addi a1, a1, -1572; RV64I-NEXT: add a0, a0, a1573; RV64I-NEXT: ret574;575; RV32I-LABEL: add_lo_negone:576; RV32I: # %bb.0:577; RV32I-NEXT: snez a2, a0578; RV32I-NEXT: add a1, a1, a2579; RV32I-NEXT: addi a1, a1, -2580; RV32I-NEXT: addi a0, a0, -1581; RV32I-NEXT: ret582 %2 = add nsw i64 %0, -4294967297583 ret i64 %2584}585 586define i64 @add_hi_one_lo_negone(i64 %0) {587; RV64I-LABEL: add_hi_one_lo_negone:588; RV64I: # %bb.0:589; RV64I-NEXT: li a1, -1590; RV64I-NEXT: srli a1, a1, 31591; RV64I-NEXT: add a0, a0, a1592; RV64I-NEXT: ret593;594; RV32I-LABEL: add_hi_one_lo_negone:595; RV32I: # %bb.0:596; RV32I-NEXT: snez a2, a0597; RV32I-NEXT: add a1, a1, a2598; RV32I-NEXT: addi a1, a1, 1599; RV32I-NEXT: addi a0, a0, -1600; RV32I-NEXT: ret601 %2 = add nsw i64 %0, 8589934591602 ret i64 %2603}604