diff --git a/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll @@ -0,0 +1,277 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -verify-machineinstrs -no-integrated-as < %s \ +; RUN: | FileCheck -check-prefixes=RV32I %s +; RUN: llc -mtriple=riscv64 -verify-machineinstrs -no-integrated-as < %s \ +; RUN: | FileCheck -check-prefixes=RV64I %s +; RUN: llc -mtriple=riscv32 -code-model=medium -verify-machineinstrs -no-integrated-as < %s \ +; RUN: | FileCheck -check-prefixes=RV32I-MEDIUM %s +; RUN: llc -mtriple=riscv64 -code-model=medium -verify-machineinstrs -no-integrated-as < %s \ +; RUN: | FileCheck -check-prefixes=RV64I-MEDIUM %s + +define void @constraint_m_1(ptr %a) nounwind { +; RV32I-LABEL: constraint_m_1: +; RV32I: # %bb.0: +; RV32I-NEXT: #APP +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_m_1: +; RV64I: # %bb.0: +; RV64I-NEXT: #APP +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret +; +; RV32I-MEDIUM-LABEL: constraint_m_1: +; RV32I-MEDIUM: # %bb.0: +; RV32I-MEDIUM-NEXT: #APP +; RV32I-MEDIUM-NEXT: #NO_APP +; RV32I-MEDIUM-NEXT: ret +; +; RV64I-MEDIUM-LABEL: constraint_m_1: +; RV64I-MEDIUM: # %bb.0: +; RV64I-MEDIUM-NEXT: #APP +; RV64I-MEDIUM-NEXT: #NO_APP +; RV64I-MEDIUM-NEXT: ret + call void asm sideeffect "", "=*m"(ptr elementtype(i32) %a) + ret void +} + +define i32 @constraint_m_2(ptr %a) nounwind { +; RV32I-LABEL: constraint_m_2: +; RV32I: # %bb.0: +; RV32I-NEXT: #APP +; RV32I-NEXT: lw a0, 0(a0) +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_m_2: +; RV64I: # %bb.0: +; RV64I-NEXT: #APP +; RV64I-NEXT: lw a0, 0(a0) +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret +; +; RV32I-MEDIUM-LABEL: constraint_m_2: +; RV32I-MEDIUM: # %bb.0: +; RV32I-MEDIUM-NEXT: #APP +; RV32I-MEDIUM-NEXT: lw a0, 0(a0) +; RV32I-MEDIUM-NEXT: #NO_APP +; RV32I-MEDIUM-NEXT: ret +; +; RV64I-MEDIUM-LABEL: constraint_m_2: +; RV64I-MEDIUM: # %bb.0: +; RV64I-MEDIUM-NEXT: #APP +; RV64I-MEDIUM-NEXT: lw a0, 0(a0) +; RV64I-MEDIUM-NEXT: #NO_APP +; RV64I-MEDIUM-NEXT: ret + %1 = tail call i32 asm "lw $0, $1", "=r,*m"(ptr elementtype(i32) %a) + ret i32 %1 +} + +define i32 @constraint_m_with_offset(ptr %a) nounwind { +; RV32I-LABEL: constraint_m_with_offset: +; RV32I: # %bb.0: +; RV32I-NEXT: #APP +; RV32I-NEXT: lw a0, 4(a0) +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_m_with_offset: +; RV64I: # %bb.0: +; RV64I-NEXT: #APP +; RV64I-NEXT: lw a0, 4(a0) +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret +; +; RV32I-MEDIUM-LABEL: constraint_m_with_offset: +; RV32I-MEDIUM: # %bb.0: +; RV32I-MEDIUM-NEXT: #APP +; RV32I-MEDIUM-NEXT: lw a0, 4(a0) +; RV32I-MEDIUM-NEXT: #NO_APP +; RV32I-MEDIUM-NEXT: ret +; +; RV64I-MEDIUM-LABEL: constraint_m_with_offset: +; RV64I-MEDIUM: # %bb.0: +; RV64I-MEDIUM-NEXT: #APP +; RV64I-MEDIUM-NEXT: lw a0, 4(a0) +; RV64I-MEDIUM-NEXT: #NO_APP +; RV64I-MEDIUM-NEXT: ret + %1 = getelementptr i32, ptr %a, i32 1 + %2 = tail call i32 asm "lw $0, $1", "=r,*m"(ptr elementtype(i32) %1) + ret i32 %2 +} + +define void @constraint_o_1(ptr %a) nounwind { +; RV32I-LABEL: constraint_o_1: +; RV32I: # %bb.0: +; RV32I-NEXT: #APP +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_o_1: +; RV64I: # %bb.0: +; RV64I-NEXT: #APP +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret +; +; RV32I-MEDIUM-LABEL: constraint_o_1: +; RV32I-MEDIUM: # %bb.0: +; RV32I-MEDIUM-NEXT: #APP +; RV32I-MEDIUM-NEXT: #NO_APP +; RV32I-MEDIUM-NEXT: ret +; +; RV64I-MEDIUM-LABEL: constraint_o_1: +; RV64I-MEDIUM: # %bb.0: +; RV64I-MEDIUM-NEXT: #APP +; RV64I-MEDIUM-NEXT: #NO_APP +; RV64I-MEDIUM-NEXT: ret + call void asm sideeffect "", "=*o"(ptr elementtype(i32) %a) + ret void +} + +define i32 @constraint_o_2(ptr %a) nounwind { +; RV32I-LABEL: constraint_o_2: +; RV32I: # %bb.0: +; RV32I-NEXT: #APP +; RV32I-NEXT: lw a0, 0(a0) +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_o_2: +; RV64I: # %bb.0: +; RV64I-NEXT: #APP +; RV64I-NEXT: lw a0, 0(a0) +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret +; +; RV32I-MEDIUM-LABEL: constraint_o_2: +; RV32I-MEDIUM: # %bb.0: +; RV32I-MEDIUM-NEXT: #APP +; RV32I-MEDIUM-NEXT: lw a0, 0(a0) +; RV32I-MEDIUM-NEXT: #NO_APP +; RV32I-MEDIUM-NEXT: ret +; +; RV64I-MEDIUM-LABEL: constraint_o_2: +; RV64I-MEDIUM: # %bb.0: +; RV64I-MEDIUM-NEXT: #APP +; RV64I-MEDIUM-NEXT: lw a0, 0(a0) +; RV64I-MEDIUM-NEXT: #NO_APP +; RV64I-MEDIUM-NEXT: ret + %1 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %a) + ret i32 %1 +} + +define i32 @constraint_o_with_offset(ptr %a) nounwind { +; RV32I-LABEL: constraint_o_with_offset: +; RV32I: # %bb.0: +; RV32I-NEXT: #APP +; RV32I-NEXT: lw a0, 4(a0) +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_o_with_offset: +; RV64I: # %bb.0: +; RV64I-NEXT: #APP +; RV64I-NEXT: lw a0, 4(a0) +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret +; +; RV32I-MEDIUM-LABEL: constraint_o_with_offset: +; RV32I-MEDIUM: # %bb.0: +; RV32I-MEDIUM-NEXT: #APP +; RV32I-MEDIUM-NEXT: lw a0, 4(a0) +; RV32I-MEDIUM-NEXT: #NO_APP +; RV32I-MEDIUM-NEXT: ret +; +; RV64I-MEDIUM-LABEL: constraint_o_with_offset: +; RV64I-MEDIUM: # %bb.0: +; RV64I-MEDIUM-NEXT: #APP +; RV64I-MEDIUM-NEXT: lw a0, 4(a0) +; RV64I-MEDIUM-NEXT: #NO_APP +; RV64I-MEDIUM-NEXT: ret + %1 = getelementptr i32, ptr %a, i32 1 + %2 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %1) + ret i32 %2 +} + +define void @constraint_A(ptr %a) nounwind { +; RV32I-LABEL: constraint_A: +; RV32I: # %bb.0: +; RV32I-NEXT: #APP +; RV32I-NEXT: sb s0, 0(a0) +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: #APP +; RV32I-NEXT: lb s1, 0(a0) +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_A: +; RV64I: # %bb.0: +; RV64I-NEXT: #APP +; RV64I-NEXT: sb s0, 0(a0) +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: #APP +; RV64I-NEXT: lb s1, 0(a0) +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret +; +; RV32I-MEDIUM-LABEL: constraint_A: +; RV32I-MEDIUM: # %bb.0: +; RV32I-MEDIUM-NEXT: #APP +; RV32I-MEDIUM-NEXT: sb s0, 0(a0) +; RV32I-MEDIUM-NEXT: #NO_APP +; RV32I-MEDIUM-NEXT: #APP +; RV32I-MEDIUM-NEXT: lb s1, 0(a0) +; RV32I-MEDIUM-NEXT: #NO_APP +; RV32I-MEDIUM-NEXT: ret +; +; RV64I-MEDIUM-LABEL: constraint_A: +; RV64I-MEDIUM: # %bb.0: +; RV64I-MEDIUM-NEXT: #APP +; RV64I-MEDIUM-NEXT: sb s0, 0(a0) +; RV64I-MEDIUM-NEXT: #NO_APP +; RV64I-MEDIUM-NEXT: #APP +; RV64I-MEDIUM-NEXT: lb s1, 0(a0) +; RV64I-MEDIUM-NEXT: #NO_APP +; RV64I-MEDIUM-NEXT: ret + tail call void asm sideeffect "sb s0, $0", "*A"(ptr elementtype(i8) %a) + tail call void asm sideeffect "lb s1, $0", "*A"(ptr elementtype(i8) %a) + ret void +} + +define i32 @constraint_A_with_offset(ptr %a) nounwind { +; RV32I-LABEL: constraint_A_with_offset: +; RV32I: # %bb.0: +; RV32I-NEXT: addi a0, a0, 4 +; RV32I-NEXT: #APP +; RV32I-NEXT: lw a0, 0(a0) +; RV32I-NEXT: #NO_APP +; RV32I-NEXT: ret +; +; RV64I-LABEL: constraint_A_with_offset: +; RV64I: # %bb.0: +; RV64I-NEXT: addi a0, a0, 4 +; RV64I-NEXT: #APP +; RV64I-NEXT: lw a0, 0(a0) +; RV64I-NEXT: #NO_APP +; RV64I-NEXT: ret +; +; RV32I-MEDIUM-LABEL: constraint_A_with_offset: +; RV32I-MEDIUM: # %bb.0: +; RV32I-MEDIUM-NEXT: addi a0, a0, 4 +; RV32I-MEDIUM-NEXT: #APP +; RV32I-MEDIUM-NEXT: lw a0, 0(a0) +; RV32I-MEDIUM-NEXT: #NO_APP +; RV32I-MEDIUM-NEXT: ret +; +; RV64I-MEDIUM-LABEL: constraint_A_with_offset: +; RV64I-MEDIUM: # %bb.0: +; RV64I-MEDIUM-NEXT: addi a0, a0, 4 +; RV64I-MEDIUM-NEXT: #APP +; RV64I-MEDIUM-NEXT: lw a0, 0(a0) +; RV64I-MEDIUM-NEXT: #NO_APP +; RV64I-MEDIUM-NEXT: ret + %1 = getelementptr i32, ptr %a, i32 1 + %2 = tail call i32 asm "lw $0, $1", "=r,*A"(ptr elementtype(i32) %1) + ret i32 %2 +} diff --git a/llvm/test/CodeGen/RISCV/inline-asm.ll b/llvm/test/CodeGen/RISCV/inline-asm.ll --- a/llvm/test/CodeGen/RISCV/inline-asm.ll +++ b/llvm/test/CodeGen/RISCV/inline-asm.ll @@ -75,112 +75,6 @@ ret i32 %2 } -define void @constraint_m(ptr %a) nounwind { -; RV32I-LABEL: constraint_m: -; RV32I: # %bb.0: -; RV32I-NEXT: #APP -; RV32I-NEXT: #NO_APP -; RV32I-NEXT: ret -; -; RV64I-LABEL: constraint_m: -; RV64I: # %bb.0: -; RV64I-NEXT: #APP -; RV64I-NEXT: #NO_APP -; RV64I-NEXT: ret - call void asm sideeffect "", "=*m"(ptr elementtype(i32) %a) - ret void -} - -define i32 @constraint_m2(ptr %a) nounwind { -; RV32I-LABEL: constraint_m2: -; RV32I: # %bb.0: -; RV32I-NEXT: #APP -; RV32I-NEXT: lw a0, 0(a0) -; RV32I-NEXT: #NO_APP -; RV32I-NEXT: ret -; -; RV64I-LABEL: constraint_m2: -; RV64I: # %bb.0: -; RV64I-NEXT: #APP -; RV64I-NEXT: lw a0, 0(a0) -; RV64I-NEXT: #NO_APP -; RV64I-NEXT: ret - %1 = tail call i32 asm "lw $0, $1", "=r,*m"(ptr elementtype(i32) %a) - ret i32 %1 -} - -define i32 @constraint_m_with_offset(ptr %a) nounwind { -; RV32I-LABEL: constraint_m_with_offset: -; RV32I: # %bb.0: -; RV32I-NEXT: #APP -; RV32I-NEXT: lw a0, 4(a0) -; RV32I-NEXT: #NO_APP -; RV32I-NEXT: ret -; -; RV64I-LABEL: constraint_m_with_offset: -; RV64I: # %bb.0: -; RV64I-NEXT: #APP -; RV64I-NEXT: lw a0, 4(a0) -; RV64I-NEXT: #NO_APP -; RV64I-NEXT: ret - %1 = getelementptr i32, ptr %a, i32 1 - %2 = tail call i32 asm "lw $0, $1", "=r,*m"(ptr elementtype(i32) %1) - ret i32 %2 -} - -define void @constraint_o(ptr %a) nounwind { -; RV32I-LABEL: constraint_o: -; RV32I: # %bb.0: -; RV32I-NEXT: #APP -; RV32I-NEXT: #NO_APP -; RV32I-NEXT: ret -; -; RV64I-LABEL: constraint_o: -; RV64I: # %bb.0: -; RV64I-NEXT: #APP -; RV64I-NEXT: #NO_APP -; RV64I-NEXT: ret - call void asm sideeffect "", "=*o"(ptr elementtype(i32) %a) - ret void -} - -define i32 @constraint_o2(ptr %a) nounwind { -; RV32I-LABEL: constraint_o2: -; RV32I: # %bb.0: -; RV32I-NEXT: #APP -; RV32I-NEXT: lw a0, 0(a0) -; RV32I-NEXT: #NO_APP -; RV32I-NEXT: ret -; -; RV64I-LABEL: constraint_o2: -; RV64I: # %bb.0: -; RV64I-NEXT: #APP -; RV64I-NEXT: lw a0, 0(a0) -; RV64I-NEXT: #NO_APP -; RV64I-NEXT: ret - %1 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %a) - ret i32 %1 -} - -define i32 @constraint_o_with_offset(ptr %a) nounwind { -; RV32I-LABEL: constraint_o_with_offset: -; RV32I: # %bb.0: -; RV32I-NEXT: #APP -; RV32I-NEXT: lw a0, 4(a0) -; RV32I-NEXT: #NO_APP -; RV32I-NEXT: ret -; -; RV64I-LABEL: constraint_o_with_offset: -; RV64I: # %bb.0: -; RV64I-NEXT: #APP -; RV64I-NEXT: lw a0, 4(a0) -; RV64I-NEXT: #NO_APP -; RV64I-NEXT: ret - %1 = getelementptr i32, ptr %a, i32 1 - %2 = tail call i32 asm "lw $0, $1", "=r,*o"(ptr elementtype(i32) %1) - ret i32 %2 -} - define void @constraint_I() nounwind { ; RV32I-LABEL: constraint_I: ; RV32I: # %bb.0: @@ -249,52 +143,6 @@ ret void } -define void @constraint_A(ptr %a) nounwind { -; RV32I-LABEL: constraint_A: -; RV32I: # %bb.0: -; RV32I-NEXT: #APP -; RV32I-NEXT: sb s0, 0(a0) -; RV32I-NEXT: #NO_APP -; RV32I-NEXT: #APP -; RV32I-NEXT: lb s1, 0(a0) -; RV32I-NEXT: #NO_APP -; RV32I-NEXT: ret -; -; RV64I-LABEL: constraint_A: -; RV64I: # %bb.0: -; RV64I-NEXT: #APP -; RV64I-NEXT: sb s0, 0(a0) -; RV64I-NEXT: #NO_APP -; RV64I-NEXT: #APP -; RV64I-NEXT: lb s1, 0(a0) -; RV64I-NEXT: #NO_APP -; RV64I-NEXT: ret - tail call void asm sideeffect "sb s0, $0", "*A"(ptr elementtype(i8) %a) - tail call void asm sideeffect "lb s1, $0", "*A"(ptr elementtype(i8) %a) - ret void -} - -define i32 @constraint_A_with_offset(ptr %a) nounwind { -; RV32I-LABEL: constraint_A_with_offset: -; RV32I: # %bb.0: -; RV32I-NEXT: addi a0, a0, 4 -; RV32I-NEXT: #APP -; RV32I-NEXT: lw a0, 0(a0) -; RV32I-NEXT: #NO_APP -; RV32I-NEXT: ret -; -; RV64I-LABEL: constraint_A_with_offset: -; RV64I: # %bb.0: -; RV64I-NEXT: addi a0, a0, 4 -; RV64I-NEXT: #APP -; RV64I-NEXT: lw a0, 0(a0) -; RV64I-NEXT: #NO_APP -; RV64I-NEXT: ret - %1 = getelementptr i32, ptr %a, i32 1 - %2 = tail call i32 asm "lw $0, $1", "=r,*A"(ptr elementtype(i32) %1) - ret i32 %2 -} - define i32 @modifier_z_zero(i32 %a) nounwind { ; RV32I-LABEL: modifier_z_zero: ; RV32I: # %bb.0: