1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefix=RV32I 4; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefix=RV64I 6 7; These tests are each targeted at a particular RISC-V ALU instruction. Most 8; other files in this folder exercise LLVM IR instructions that don't directly 9; match a RISC-V instruction. 10 11; Register-immediate instructions. 12 13; TODO: Sign-extension would also work when promoting the operands of 14; sltu/sltiu on RV64 and is cheaper than zero-extension (1 instruction vs 2). 15 16define i32 @addi(i32 %a) nounwind { 17; RV32I-LABEL: addi: 18; RV32I: # %bb.0: 19; RV32I-NEXT: addi a0, a0, 1 20; RV32I-NEXT: ret 21; 22; RV64I-LABEL: addi: 23; RV64I: # %bb.0: 24; RV64I-NEXT: addi a0, a0, 1 25; RV64I-NEXT: ret 26 %1 = add i32 %a, 1 27 ret i32 %1 28} 29 30define i32 @slti(i32 %a) nounwind { 31; RV32I-LABEL: slti: 32; RV32I: # %bb.0: 33; RV32I-NEXT: slti a0, a0, 2 34; RV32I-NEXT: ret 35; 36; RV64I-LABEL: slti: 37; RV64I: # %bb.0: 38; RV64I-NEXT: sext.w a0, a0 39; RV64I-NEXT: slti a0, a0, 2 40; RV64I-NEXT: ret 41 %1 = icmp slt i32 %a, 2 42 %2 = zext i1 %1 to i32 43 ret i32 %2 44} 45 46define i32 @sltiu(i32 %a) nounwind { 47; RV32I-LABEL: sltiu: 48; RV32I: # %bb.0: 49; RV32I-NEXT: sltiu a0, a0, 3 50; RV32I-NEXT: ret 51; 52; RV64I-LABEL: sltiu: 53; RV64I: # %bb.0: 54; RV64I-NEXT: sext.w a0, a0 55; RV64I-NEXT: sltiu a0, a0, 3 56; RV64I-NEXT: ret 57 %1 = icmp ult i32 %a, 3 58 %2 = zext i1 %1 to i32 59 ret i32 %2 60} 61 62define i32 @xori(i32 %a) nounwind { 63; RV32I-LABEL: xori: 64; RV32I: # %bb.0: 65; RV32I-NEXT: xori a0, a0, 4 66; RV32I-NEXT: ret 67; 68; RV64I-LABEL: xori: 69; RV64I: # %bb.0: 70; RV64I-NEXT: xori a0, a0, 4 71; RV64I-NEXT: ret 72 %1 = xor i32 %a, 4 73 ret i32 %1 74} 75 76define i32 @ori(i32 %a) nounwind { 77; RV32I-LABEL: ori: 78; RV32I: # %bb.0: 79; RV32I-NEXT: ori a0, a0, 5 80; RV32I-NEXT: ret 81; 82; RV64I-LABEL: ori: 83; RV64I: # %bb.0: 84; RV64I-NEXT: ori a0, a0, 5 85; RV64I-NEXT: ret 86 %1 = or i32 %a, 5 87 ret i32 %1 88} 89 90define i32 @andi(i32 %a) nounwind { 91; RV32I-LABEL: andi: 92; RV32I: # %bb.0: 93; RV32I-NEXT: andi a0, a0, 6 94; RV32I-NEXT: ret 95; 96; RV64I-LABEL: andi: 97; RV64I: # %bb.0: 98; RV64I-NEXT: andi a0, a0, 6 99; RV64I-NEXT: ret 100 %1 = and i32 %a, 6 101 ret i32 %1 102} 103 104define i32 @slli(i32 %a) nounwind { 105; RV32I-LABEL: slli: 106; RV32I: # %bb.0: 107; RV32I-NEXT: slli a0, a0, 7 108; RV32I-NEXT: ret 109; 110; RV64I-LABEL: slli: 111; RV64I: # %bb.0: 112; RV64I-NEXT: slli a0, a0, 7 113; RV64I-NEXT: ret 114 %1 = shl i32 %a, 7 115 ret i32 %1 116} 117 118define i32 @srli(i32 %a) nounwind { 119; RV32I-LABEL: srli: 120; RV32I: # %bb.0: 121; RV32I-NEXT: srli a0, a0, 8 122; RV32I-NEXT: ret 123; 124; RV64I-LABEL: srli: 125; RV64I: # %bb.0: 126; RV64I-NEXT: srliw a0, a0, 8 127; RV64I-NEXT: ret 128 %1 = lshr i32 %a, 8 129 ret i32 %1 130} 131 132define i32 @srai(i32 %a) nounwind { 133; RV32I-LABEL: srai: 134; RV32I: # %bb.0: 135; RV32I-NEXT: srai a0, a0, 9 136; RV32I-NEXT: ret 137; 138; RV64I-LABEL: srai: 139; RV64I: # %bb.0: 140; RV64I-NEXT: sraiw a0, a0, 9 141; RV64I-NEXT: ret 142 %1 = ashr i32 %a, 9 143 ret i32 %1 144} 145 146; Register-register instructions 147 148define i32 @add(i32 %a, i32 %b) nounwind { 149; RV32I-LABEL: add: 150; RV32I: # %bb.0: 151; RV32I-NEXT: add a0, a0, a1 152; RV32I-NEXT: ret 153; 154; RV64I-LABEL: add: 155; RV64I: # %bb.0: 156; RV64I-NEXT: addw a0, a0, a1 157; RV64I-NEXT: ret 158 %1 = add i32 %a, %b 159 ret i32 %1 160} 161 162define i32 @sub(i32 %a, i32 %b) nounwind { 163; RV32I-LABEL: sub: 164; RV32I: # %bb.0: 165; RV32I-NEXT: sub a0, a0, a1 166; RV32I-NEXT: ret 167; 168; RV64I-LABEL: sub: 169; RV64I: # %bb.0: 170; RV64I-NEXT: subw a0, a0, a1 171; RV64I-NEXT: ret 172 %1 = sub i32 %a, %b 173 ret i32 %1 174} 175 176define i32 @sll(i32 %a, i32 %b) nounwind { 177; RV32I-LABEL: sll: 178; RV32I: # %bb.0: 179; RV32I-NEXT: sll a0, a0, a1 180; RV32I-NEXT: ret 181; 182; RV64I-LABEL: sll: 183; RV64I: # %bb.0: 184; RV64I-NEXT: sllw a0, a0, a1 185; RV64I-NEXT: ret 186 %1 = shl i32 %a, %b 187 ret i32 %1 188} 189 190define i32 @slt(i32 %a, i32 %b) nounwind { 191; RV32I-LABEL: slt: 192; RV32I: # %bb.0: 193; RV32I-NEXT: slt a0, a0, a1 194; RV32I-NEXT: ret 195; 196; RV64I-LABEL: slt: 197; RV64I: # %bb.0: 198; RV64I-NEXT: sext.w a1, a1 199; RV64I-NEXT: sext.w a0, a0 200; RV64I-NEXT: slt a0, a0, a1 201; RV64I-NEXT: ret 202 %1 = icmp slt i32 %a, %b 203 %2 = zext i1 %1 to i32 204 ret i32 %2 205} 206 207define i32 @sltu(i32 %a, i32 %b) nounwind { 208; RV32I-LABEL: sltu: 209; RV32I: # %bb.0: 210; RV32I-NEXT: sltu a0, a0, a1 211; RV32I-NEXT: ret 212; 213; RV64I-LABEL: sltu: 214; RV64I: # %bb.0: 215; RV64I-NEXT: sext.w a1, a1 216; RV64I-NEXT: sext.w a0, a0 217; RV64I-NEXT: sltu a0, a0, a1 218; RV64I-NEXT: ret 219 %1 = icmp ult i32 %a, %b 220 %2 = zext i1 %1 to i32 221 ret i32 %2 222} 223 224define i32 @xor(i32 %a, i32 %b) nounwind { 225; RV32I-LABEL: xor: 226; RV32I: # %bb.0: 227; RV32I-NEXT: xor a0, a0, a1 228; RV32I-NEXT: ret 229; 230; RV64I-LABEL: xor: 231; RV64I: # %bb.0: 232; RV64I-NEXT: xor a0, a0, a1 233; RV64I-NEXT: ret 234 %1 = xor i32 %a, %b 235 ret i32 %1 236} 237 238define i32 @srl(i32 %a, i32 %b) nounwind { 239; RV32I-LABEL: srl: 240; RV32I: # %bb.0: 241; RV32I-NEXT: srl a0, a0, a1 242; RV32I-NEXT: ret 243; 244; RV64I-LABEL: srl: 245; RV64I: # %bb.0: 246; RV64I-NEXT: srlw a0, a0, a1 247; RV64I-NEXT: ret 248 %1 = lshr i32 %a, %b 249 ret i32 %1 250} 251 252define i32 @sra(i32 %a, i32 %b) nounwind { 253; RV32I-LABEL: sra: 254; RV32I: # %bb.0: 255; RV32I-NEXT: sra a0, a0, a1 256; RV32I-NEXT: ret 257; 258; RV64I-LABEL: sra: 259; RV64I: # %bb.0: 260; RV64I-NEXT: sraw a0, a0, a1 261; RV64I-NEXT: ret 262 %1 = ashr i32 %a, %b 263 ret i32 %1 264} 265 266define i32 @or(i32 %a, i32 %b) nounwind { 267; RV32I-LABEL: or: 268; RV32I: # %bb.0: 269; RV32I-NEXT: or a0, a0, a1 270; RV32I-NEXT: ret 271; 272; RV64I-LABEL: or: 273; RV64I: # %bb.0: 274; RV64I-NEXT: or a0, a0, a1 275; RV64I-NEXT: ret 276 %1 = or i32 %a, %b 277 ret i32 %1 278} 279 280define i32 @and(i32 %a, i32 %b) nounwind { 281; RV32I-LABEL: and: 282; RV32I: # %bb.0: 283; RV32I-NEXT: and a0, a0, a1 284; RV32I-NEXT: ret 285; 286; RV64I-LABEL: and: 287; RV64I: # %bb.0: 288; RV64I-NEXT: and a0, a0, a1 289; RV64I-NEXT: ret 290 %1 = and i32 %a, %b 291 ret i32 %1 292} 293