327 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -verify-machineinstrs -no-integrated-as < %s \3; RUN: | FileCheck -check-prefix=RV32I %s4; RUN: llc -mtriple=riscv64 -verify-machineinstrs -no-integrated-as < %s \5; RUN: | FileCheck -check-prefix=RV64I %s6 7@gi = external global i328 9define i32 @constraint_r(i32 %a) nounwind {10; RV32I-LABEL: constraint_r:11; RV32I: # %bb.0:12; RV32I-NEXT: lui a1, %hi(gi)13; RV32I-NEXT: lw a1, %lo(gi)(a1)14; RV32I-NEXT: #APP15; RV32I-NEXT: add a0, a0, a116; RV32I-NEXT: #NO_APP17; RV32I-NEXT: ret18;19; RV64I-LABEL: constraint_r:20; RV64I: # %bb.0:21; RV64I-NEXT: lui a1, %hi(gi)22; RV64I-NEXT: lw a1, %lo(gi)(a1)23; RV64I-NEXT: #APP24; RV64I-NEXT: add a0, a0, a125; RV64I-NEXT: #NO_APP26; RV64I-NEXT: ret27 %1 = load i32, ptr @gi28 %2 = tail call i32 asm "add $0, $1, $2", "=r,r,r"(i32 %a, i32 %1)29 ret i32 %230}31 32; Don't allow 'x0' for 'r'. Some instructions have a different behavior when33; x0 is encoded.34define i32 @constraint_r_zero(i32 %a) nounwind {35; RV32I-LABEL: constraint_r_zero:36; RV32I: # %bb.0:37; RV32I-NEXT: lui a0, %hi(gi)38; RV32I-NEXT: lw a0, %lo(gi)(a0)39; RV32I-NEXT: li a1, 040; RV32I-NEXT: #APP41; RV32I-NEXT: add a0, a1, a042; RV32I-NEXT: #NO_APP43; RV32I-NEXT: ret44;45; RV64I-LABEL: constraint_r_zero:46; RV64I: # %bb.0:47; RV64I-NEXT: lui a0, %hi(gi)48; RV64I-NEXT: lw a0, %lo(gi)(a0)49; RV64I-NEXT: li a1, 050; RV64I-NEXT: #APP51; RV64I-NEXT: add a0, a1, a052; RV64I-NEXT: #NO_APP53; RV64I-NEXT: ret54 %1 = load i32, ptr @gi55 %2 = tail call i32 asm "add $0, $1, $2", "=r,r,r"(i32 0, i32 %1)56 ret i32 %257}58 59define i32 @constraint_cr(i32 %a) nounwind {60; RV32I-LABEL: constraint_cr:61; RV32I: # %bb.0:62; RV32I-NEXT: lui a1, %hi(gi)63; RV32I-NEXT: lw a1, %lo(gi)(a1)64; RV32I-NEXT: #APP65; RV32I-NEXT: c.add a0, a0, a166; RV32I-NEXT: #NO_APP67; RV32I-NEXT: ret68;69; RV64I-LABEL: constraint_cr:70; RV64I: # %bb.0:71; RV64I-NEXT: lui a1, %hi(gi)72; RV64I-NEXT: lw a1, %lo(gi)(a1)73; RV64I-NEXT: #APP74; RV64I-NEXT: c.add a0, a0, a175; RV64I-NEXT: #NO_APP76; RV64I-NEXT: ret77 %1 = load i32, ptr @gi78 %2 = tail call i32 asm "c.add $0, $1, $2", "=^cr,0,^cr"(i32 %a, i32 %1)79 ret i32 %280}81 82define i32 @constraint_i(i32 %a) nounwind {83; RV32I-LABEL: constraint_i:84; RV32I: # %bb.0:85; RV32I-NEXT: #APP86; RV32I-NEXT: addi a0, a0, 11387; RV32I-NEXT: #NO_APP88; RV32I-NEXT: ret89;90; RV64I-LABEL: constraint_i:91; RV64I: # %bb.0:92; RV64I-NEXT: #APP93; RV64I-NEXT: addi a0, a0, 11394; RV64I-NEXT: #NO_APP95; RV64I-NEXT: ret96 %1 = load i32, ptr @gi97 %2 = tail call i32 asm "addi $0, $1, $2", "=r,r,i"(i32 %a, i32 113)98 ret i32 %299}100 101define void @constraint_I() nounwind {102; RV32I-LABEL: constraint_I:103; RV32I: # %bb.0:104; RV32I-NEXT: #APP105; RV32I-NEXT: addi a0, a0, 2047106; RV32I-NEXT: #NO_APP107; RV32I-NEXT: #APP108; RV32I-NEXT: addi a0, a0, -2048109; RV32I-NEXT: #NO_APP110; RV32I-NEXT: ret111;112; RV64I-LABEL: constraint_I:113; RV64I: # %bb.0:114; RV64I-NEXT: #APP115; RV64I-NEXT: addi a0, a0, 2047116; RV64I-NEXT: #NO_APP117; RV64I-NEXT: #APP118; RV64I-NEXT: addi a0, a0, -2048119; RV64I-NEXT: #NO_APP120; RV64I-NEXT: ret121 tail call void asm sideeffect "addi a0, a0, $0", "I"(i32 2047)122 tail call void asm sideeffect "addi a0, a0, $0", "I"(i32 -2048)123 ret void124}125 126define void @constraint_J() nounwind {127; RV32I-LABEL: constraint_J:128; RV32I: # %bb.0:129; RV32I-NEXT: #APP130; RV32I-NEXT: addi a0, a0, 0131; RV32I-NEXT: #NO_APP132; RV32I-NEXT: ret133;134; RV64I-LABEL: constraint_J:135; RV64I: # %bb.0:136; RV64I-NEXT: #APP137; RV64I-NEXT: addi a0, a0, 0138; RV64I-NEXT: #NO_APP139; RV64I-NEXT: ret140 tail call void asm sideeffect "addi a0, a0, $0", "J"(i32 0)141 ret void142}143 144define void @constraint_K() nounwind {145; RV32I-LABEL: constraint_K:146; RV32I: # %bb.0:147; RV32I-NEXT: #APP148; RV32I-NEXT: csrwi mstatus, 31149; RV32I-NEXT: #NO_APP150; RV32I-NEXT: #APP151; RV32I-NEXT: csrwi mstatus, 0152; RV32I-NEXT: #NO_APP153; RV32I-NEXT: ret154;155; RV64I-LABEL: constraint_K:156; RV64I: # %bb.0:157; RV64I-NEXT: #APP158; RV64I-NEXT: csrwi mstatus, 31159; RV64I-NEXT: #NO_APP160; RV64I-NEXT: #APP161; RV64I-NEXT: csrwi mstatus, 0162; RV64I-NEXT: #NO_APP163; RV64I-NEXT: ret164 tail call void asm sideeffect "csrwi mstatus, $0", "K"(i32 31)165 tail call void asm sideeffect "csrwi mstatus, $0", "K"(i32 0)166 ret void167}168 169define i32 @modifier_z_zero(i32 %a) nounwind {170; RV32I-LABEL: modifier_z_zero:171; RV32I: # %bb.0:172; RV32I-NEXT: #APP173; RV32I-NEXT: add a0, a0, zero174; RV32I-NEXT: #NO_APP175; RV32I-NEXT: ret176;177; RV64I-LABEL: modifier_z_zero:178; RV64I: # %bb.0:179; RV64I-NEXT: #APP180; RV64I-NEXT: add a0, a0, zero181; RV64I-NEXT: #NO_APP182; RV64I-NEXT: ret183 %1 = tail call i32 asm "add $0, $1, ${2:z}", "=r,r,i"(i32 %a, i32 0)184 ret i32 %1185}186 187define i32 @modifier_z_nonzero(i32 %a) nounwind {188; RV32I-LABEL: modifier_z_nonzero:189; RV32I: # %bb.0:190; RV32I-NEXT: #APP191; RV32I-NEXT: add a0, a0, 1192; RV32I-NEXT: #NO_APP193; RV32I-NEXT: ret194;195; RV64I-LABEL: modifier_z_nonzero:196; RV64I: # %bb.0:197; RV64I-NEXT: #APP198; RV64I-NEXT: add a0, a0, 1199; RV64I-NEXT: #NO_APP200; RV64I-NEXT: ret201 %1 = tail call i32 asm "add $0, $1, ${2:z}", "=r,r,i"(i32 %a, i32 1)202 ret i32 %1203}204 205define i32 @modifier_i_imm(i32 %a) nounwind {206; RV32I-LABEL: modifier_i_imm:207; RV32I: # %bb.0:208; RV32I-NEXT: #APP209; RV32I-NEXT: addi a0, a0, 1210; RV32I-NEXT: #NO_APP211; RV32I-NEXT: ret212;213; RV64I-LABEL: modifier_i_imm:214; RV64I: # %bb.0:215; RV64I-NEXT: #APP216; RV64I-NEXT: addi a0, a0, 1217; RV64I-NEXT: #NO_APP218; RV64I-NEXT: ret219 %1 = tail call i32 asm "add${2:i} $0, $1, $2", "=r,r,ri"(i32 %a, i32 1)220 ret i32 %1221}222 223define i32 @modifier_i_reg(i32 %a, i32 %b) nounwind {224; RV32I-LABEL: modifier_i_reg:225; RV32I: # %bb.0:226; RV32I-NEXT: #APP227; RV32I-NEXT: add a0, a0, a1228; RV32I-NEXT: #NO_APP229; RV32I-NEXT: ret230;231; RV64I-LABEL: modifier_i_reg:232; RV64I: # %bb.0:233; RV64I-NEXT: #APP234; RV64I-NEXT: add a0, a0, a1235; RV64I-NEXT: #NO_APP236; RV64I-NEXT: ret237 %1 = tail call i32 asm "add${2:i} $0, $1, $2", "=r,r,ri"(i32 %a, i32 %b)238 ret i32 %1239}240 241;; `.insn 0x4, 0x33 | (${0:N} << 7) | (${1:N} << 15) | (${2:N} << 20)` is the242;; raw encoding of `add`243 244define i32 @modifier_N_reg(i32 %a, i32 %b) nounwind {245; RV32I-LABEL: modifier_N_reg:246; RV32I: # %bb.0:247; RV32I-NEXT: #APP248; RV32I-NEXT: .insn 0x4, 0x33 | (10 << 7) | (10 << 15) | (11 << 20)249; RV32I-NEXT: #NO_APP250; RV32I-NEXT: ret251;252; RV64I-LABEL: modifier_N_reg:253; RV64I: # %bb.0:254; RV64I-NEXT: #APP255; RV64I-NEXT: .insn 0x4, 0x33 | (10 << 7) | (10 << 15) | (11 << 20)256; RV64I-NEXT: #NO_APP257; RV64I-NEXT: ret258 %1 = tail call i32 asm ".insn 0x4, 0x33 | (${0:N} << 7) | (${1:N} << 15) | (${2:N} << 20)", "=r,r,r"(i32 %a, i32 %b)259 ret i32 %1260}261 262;; `.insn 0x2, 0x9422 | (${0:N} << 7) | (${2:N} << 2)` is the raw encoding of263;; `c.add` (note the constraint that the first input should be the same as the264;; output).265 266define i32 @modifier_N_with_cr_reg(i32 %a, i32 %b) nounwind {267; RV32I-LABEL: modifier_N_with_cr_reg:268; RV32I: # %bb.0:269; RV32I-NEXT: #APP270; RV32I-NEXT: .insn 0x2, 0x9422 | (10 << 7) | (11 << 2)271; RV32I-NEXT: #NO_APP272; RV32I-NEXT: ret273;274; RV64I-LABEL: modifier_N_with_cr_reg:275; RV64I: # %bb.0:276; RV64I-NEXT: #APP277; RV64I-NEXT: .insn 0x2, 0x9422 | (10 << 7) | (11 << 2)278; RV64I-NEXT: #NO_APP279; RV64I-NEXT: ret280 %1 = tail call i32 asm ".insn 0x2, 0x9422 | (${0:N} << 7) | (${2:N} << 2)", "=^cr,0,^cr"(i32 %a, i32 %b)281 ret i32 %1282}283 284define void @operand_global() nounwind {285; RV32I-LABEL: operand_global:286; RV32I: # %bb.0:287; RV32I-NEXT: #APP288; RV32I-NEXT: .8byte gi289; RV32I-NEXT: #NO_APP290; RV32I-NEXT: ret291;292; RV64I-LABEL: operand_global:293; RV64I: # %bb.0:294; RV64I-NEXT: #APP295; RV64I-NEXT: .8byte gi296; RV64I-NEXT: #NO_APP297; RV64I-NEXT: ret298 tail call void asm sideeffect ".8byte $0", "i"(ptr @gi)299 ret void300}301 302define void @operand_block_address() nounwind {303; RV32I-LABEL: operand_block_address:304; RV32I: # %bb.0:305; RV32I-NEXT: #APP306; RV32I-NEXT: j .Ltmp0307; RV32I-NEXT: #NO_APP308; RV32I-NEXT: .Ltmp0: # Block address taken309; RV32I-NEXT: # %bb.1: # %bb310; RV32I-NEXT: ret311;312; RV64I-LABEL: operand_block_address:313; RV64I: # %bb.0:314; RV64I-NEXT: #APP315; RV64I-NEXT: j .Ltmp0316; RV64I-NEXT: #NO_APP317; RV64I-NEXT: .Ltmp0: # Block address taken318; RV64I-NEXT: # %bb.1: # %bb319; RV64I-NEXT: ret320 call void asm sideeffect "j $0", "i"(ptr blockaddress(@operand_block_address, %bb))321 br label %bb322bb:323 ret void324}325 326; TODO: expand tests for more complex constraints, out of range immediates etc327