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 13define i32 @addi(i32 %a) nounwind { 14; RV32I-LABEL: addi: 15; RV32I: # %bb.0: 16; RV32I-NEXT: addi a0, a0, 1 17; RV32I-NEXT: ret 18; 19; RV64I-LABEL: addi: 20; RV64I: # %bb.0: 21; RV64I-NEXT: addiw a0, a0, 1 22; RV64I-NEXT: ret 23 %1 = add i32 %a, 1 24 ret i32 %1 25} 26 27define i32 @slti(i32 %a) nounwind { 28; RV32I-LABEL: slti: 29; RV32I: # %bb.0: 30; RV32I-NEXT: slti a0, a0, 2 31; RV32I-NEXT: ret 32; 33; RV64I-LABEL: slti: 34; RV64I: # %bb.0: 35; RV64I-NEXT: sext.w a0, a0 36; RV64I-NEXT: slti a0, a0, 2 37; RV64I-NEXT: ret 38 %1 = icmp slt i32 %a, 2 39 %2 = zext i1 %1 to i32 40 ret i32 %2 41} 42 43define i32 @sltiu(i32 %a) nounwind { 44; RV32I-LABEL: sltiu: 45; RV32I: # %bb.0: 46; RV32I-NEXT: sltiu a0, a0, 3 47; RV32I-NEXT: ret 48; 49; RV64I-LABEL: sltiu: 50; RV64I: # %bb.0: 51; RV64I-NEXT: sext.w a0, a0 52; RV64I-NEXT: sltiu a0, a0, 3 53; RV64I-NEXT: ret 54 %1 = icmp ult i32 %a, 3 55 %2 = zext i1 %1 to i32 56 ret i32 %2 57} 58 59define i32 @xori(i32 %a) nounwind { 60; RV32I-LABEL: xori: 61; RV32I: # %bb.0: 62; RV32I-NEXT: xori a0, a0, 4 63; RV32I-NEXT: ret 64; 65; RV64I-LABEL: xori: 66; RV64I: # %bb.0: 67; RV64I-NEXT: xori a0, a0, 4 68; RV64I-NEXT: ret 69 %1 = xor i32 %a, 4 70 ret i32 %1 71} 72 73define i32 @ori(i32 %a) nounwind { 74; RV32I-LABEL: ori: 75; RV32I: # %bb.0: 76; RV32I-NEXT: ori a0, a0, 5 77; RV32I-NEXT: ret 78; 79; RV64I-LABEL: ori: 80; RV64I: # %bb.0: 81; RV64I-NEXT: ori a0, a0, 5 82; RV64I-NEXT: ret 83 %1 = or i32 %a, 5 84 ret i32 %1 85} 86 87define i32 @andi(i32 %a) nounwind { 88; RV32I-LABEL: andi: 89; RV32I: # %bb.0: 90; RV32I-NEXT: andi a0, a0, 6 91; RV32I-NEXT: ret 92; 93; RV64I-LABEL: andi: 94; RV64I: # %bb.0: 95; RV64I-NEXT: andi a0, a0, 6 96; RV64I-NEXT: ret 97 %1 = and i32 %a, 6 98 ret i32 %1 99} 100 101define i32 @slli(i32 %a) nounwind { 102; RV32I-LABEL: slli: 103; RV32I: # %bb.0: 104; RV32I-NEXT: slli a0, a0, 7 105; RV32I-NEXT: ret 106; 107; RV64I-LABEL: slli: 108; RV64I: # %bb.0: 109; RV64I-NEXT: slliw a0, a0, 7 110; RV64I-NEXT: ret 111 %1 = shl i32 %a, 7 112 ret i32 %1 113} 114 115define i32 @srli(i32 %a) nounwind { 116; RV32I-LABEL: srli: 117; RV32I: # %bb.0: 118; RV32I-NEXT: srli a0, a0, 8 119; RV32I-NEXT: ret 120; 121; RV64I-LABEL: srli: 122; RV64I: # %bb.0: 123; RV64I-NEXT: srliw a0, a0, 8 124; RV64I-NEXT: ret 125 %1 = lshr i32 %a, 8 126 ret i32 %1 127} 128 129; This makes sure SimplifyDemandedBits doesn't prevent us from matching SRLIW 130; on RV64. 131define i32 @srli_demandedbits(i32 %0) { 132; RV32I-LABEL: srli_demandedbits: 133; RV32I: # %bb.0: 134; RV32I-NEXT: srli a0, a0, 3 135; RV32I-NEXT: ori a0, a0, 1 136; RV32I-NEXT: ret 137; 138; RV64I-LABEL: srli_demandedbits: 139; RV64I: # %bb.0: 140; RV64I-NEXT: srliw a0, a0, 3 141; RV64I-NEXT: ori a0, a0, 1 142; RV64I-NEXT: ret 143 %2 = lshr i32 %0, 3 144 %3 = or i32 %2, 1 145 ret i32 %3 146} 147 148define i32 @srai(i32 %a) nounwind { 149; RV32I-LABEL: srai: 150; RV32I: # %bb.0: 151; RV32I-NEXT: srai a0, a0, 9 152; RV32I-NEXT: ret 153; 154; RV64I-LABEL: srai: 155; RV64I: # %bb.0: 156; RV64I-NEXT: sraiw a0, a0, 9 157; RV64I-NEXT: ret 158 %1 = ashr i32 %a, 9 159 ret i32 %1 160} 161 162; Register-register instructions 163 164define i32 @add(i32 %a, i32 %b) nounwind { 165; RV32I-LABEL: add: 166; RV32I: # %bb.0: 167; RV32I-NEXT: add a0, a0, a1 168; RV32I-NEXT: ret 169; 170; RV64I-LABEL: add: 171; RV64I: # %bb.0: 172; RV64I-NEXT: addw a0, a0, a1 173; RV64I-NEXT: ret 174 %1 = add i32 %a, %b 175 ret i32 %1 176} 177 178define i32 @sub(i32 %a, i32 %b) nounwind { 179; RV32I-LABEL: sub: 180; RV32I: # %bb.0: 181; RV32I-NEXT: sub a0, a0, a1 182; RV32I-NEXT: ret 183; 184; RV64I-LABEL: sub: 185; RV64I: # %bb.0: 186; RV64I-NEXT: subw a0, a0, a1 187; RV64I-NEXT: ret 188 %1 = sub i32 %a, %b 189 ret i32 %1 190} 191 192define i32 @sub_negative_constant_lhs(i32 %a) nounwind { 193; RV32I-LABEL: sub_negative_constant_lhs: 194; RV32I: # %bb.0: 195; RV32I-NEXT: li a1, -2 196; RV32I-NEXT: sub a0, a1, a0 197; RV32I-NEXT: ret 198; 199; RV64I-LABEL: sub_negative_constant_lhs: 200; RV64I: # %bb.0: 201; RV64I-NEXT: li a1, -2 202; RV64I-NEXT: subw a0, a1, a0 203; RV64I-NEXT: ret 204 %1 = sub i32 -2, %a 205 ret i32 %1 206} 207 208define i32 @sll(i32 %a, i32 %b) nounwind { 209; RV32I-LABEL: sll: 210; RV32I: # %bb.0: 211; RV32I-NEXT: sll a0, a0, a1 212; RV32I-NEXT: ret 213; 214; RV64I-LABEL: sll: 215; RV64I: # %bb.0: 216; RV64I-NEXT: sllw a0, a0, a1 217; RV64I-NEXT: ret 218 %1 = shl i32 %a, %b 219 ret i32 %1 220} 221 222define i32 @sll_negative_constant_lhs(i32 %a) nounwind { 223; RV32I-LABEL: sll_negative_constant_lhs: 224; RV32I: # %bb.0: 225; RV32I-NEXT: li a1, -1 226; RV32I-NEXT: sll a0, a1, a0 227; RV32I-NEXT: ret 228; 229; RV64I-LABEL: sll_negative_constant_lhs: 230; RV64I: # %bb.0: 231; RV64I-NEXT: li a1, -1 232; RV64I-NEXT: sllw a0, a1, a0 233; RV64I-NEXT: ret 234 %1 = shl i32 -1, %a 235 ret i32 %1 236} 237 238define i32 @slt(i32 %a, i32 %b) nounwind { 239; RV32I-LABEL: slt: 240; RV32I: # %bb.0: 241; RV32I-NEXT: slt a0, a0, a1 242; RV32I-NEXT: ret 243; 244; RV64I-LABEL: slt: 245; RV64I: # %bb.0: 246; RV64I-NEXT: sext.w a1, a1 247; RV64I-NEXT: sext.w a0, a0 248; RV64I-NEXT: slt a0, a0, a1 249; RV64I-NEXT: ret 250 %1 = icmp slt i32 %a, %b 251 %2 = zext i1 %1 to i32 252 ret i32 %2 253} 254 255define i32 @sltu(i32 %a, i32 %b) nounwind { 256; RV32I-LABEL: sltu: 257; RV32I: # %bb.0: 258; RV32I-NEXT: sltu a0, a0, a1 259; RV32I-NEXT: ret 260; 261; RV64I-LABEL: sltu: 262; RV64I: # %bb.0: 263; RV64I-NEXT: sext.w a1, a1 264; RV64I-NEXT: sext.w a0, a0 265; RV64I-NEXT: sltu a0, a0, a1 266; RV64I-NEXT: ret 267 %1 = icmp ult i32 %a, %b 268 %2 = zext i1 %1 to i32 269 ret i32 %2 270} 271 272define i32 @xor(i32 %a, i32 %b) nounwind { 273; RV32I-LABEL: xor: 274; RV32I: # %bb.0: 275; RV32I-NEXT: xor a0, a0, a1 276; RV32I-NEXT: ret 277; 278; RV64I-LABEL: xor: 279; RV64I: # %bb.0: 280; RV64I-NEXT: xor a0, a0, a1 281; RV64I-NEXT: ret 282 %1 = xor i32 %a, %b 283 ret i32 %1 284} 285 286define i32 @srl(i32 %a, i32 %b) nounwind { 287; RV32I-LABEL: srl: 288; RV32I: # %bb.0: 289; RV32I-NEXT: srl a0, a0, a1 290; RV32I-NEXT: ret 291; 292; RV64I-LABEL: srl: 293; RV64I: # %bb.0: 294; RV64I-NEXT: srlw a0, a0, a1 295; RV64I-NEXT: ret 296 %1 = lshr i32 %a, %b 297 ret i32 %1 298} 299 300define i32 @srl_negative_constant_lhs(i32 %a) nounwind { 301; RV32I-LABEL: srl_negative_constant_lhs: 302; RV32I: # %bb.0: 303; RV32I-NEXT: li a1, -1 304; RV32I-NEXT: srl a0, a1, a0 305; RV32I-NEXT: ret 306; 307; RV64I-LABEL: srl_negative_constant_lhs: 308; RV64I: # %bb.0: 309; RV64I-NEXT: li a1, -1 310; RV64I-NEXT: srlw a0, a1, a0 311; RV64I-NEXT: ret 312 %1 = lshr i32 -1, %a 313 ret i32 %1 314} 315 316define i32 @sra(i32 %a, i32 %b) nounwind { 317; RV32I-LABEL: sra: 318; RV32I: # %bb.0: 319; RV32I-NEXT: sra a0, a0, a1 320; RV32I-NEXT: ret 321; 322; RV64I-LABEL: sra: 323; RV64I: # %bb.0: 324; RV64I-NEXT: sraw a0, a0, a1 325; RV64I-NEXT: ret 326 %1 = ashr i32 %a, %b 327 ret i32 %1 328} 329 330define i32 @sra_negative_constant_lhs(i32 %a) nounwind { 331; RV32I-LABEL: sra_negative_constant_lhs: 332; RV32I: # %bb.0: 333; RV32I-NEXT: lui a1, 524288 334; RV32I-NEXT: sra a0, a1, a0 335; RV32I-NEXT: ret 336; 337; RV64I-LABEL: sra_negative_constant_lhs: 338; RV64I: # %bb.0: 339; RV64I-NEXT: lui a1, 524288 340; RV64I-NEXT: sraw a0, a1, a0 341; RV64I-NEXT: ret 342 %1 = ashr i32 2147483648, %a 343 ret i32 %1 344} 345 346define i32 @or(i32 %a, i32 %b) nounwind { 347; RV32I-LABEL: or: 348; RV32I: # %bb.0: 349; RV32I-NEXT: or a0, a0, a1 350; RV32I-NEXT: ret 351; 352; RV64I-LABEL: or: 353; RV64I: # %bb.0: 354; RV64I-NEXT: or a0, a0, a1 355; RV64I-NEXT: ret 356 %1 = or i32 %a, %b 357 ret i32 %1 358} 359 360define i32 @and(i32 %a, i32 %b) nounwind { 361; RV32I-LABEL: and: 362; RV32I: # %bb.0: 363; RV32I-NEXT: and a0, a0, a1 364; RV32I-NEXT: ret 365; 366; RV64I-LABEL: and: 367; RV64I: # %bb.0: 368; RV64I-NEXT: and a0, a0, a1 369; RV64I-NEXT: ret 370 %1 = and i32 %a, %b 371 ret i32 %1 372} 373