| ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py |
| ; RUN: llc -mtriple=riscv32 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \ |
| ; RUN: | FileCheck -check-prefix=RV32I %s |
| ; RUN: llc -mtriple=riscv64 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \ |
| ; RUN: | FileCheck -check-prefix=RV64I %s |
| |
| declare void @void_noargs() |
| |
| define void @test_call_void_noargs() { |
| |
| ; RV32I-LABEL: name: test_call_void_noargs |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @void_noargs, csr_ilp32_lp64, implicit-def $x1 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_void_noargs |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @void_noargs, csr_ilp32_lp64, implicit-def $x1 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| call void @void_noargs() |
| ret void |
| } |
| |
| declare void @void_args_i8(i8, i8) |
| |
| define void @test_call_void_args_i8() { |
| |
| ; RV32I-LABEL: name: test_call_void_args_i8 |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0 |
| ; RV32I-NEXT: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1 |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8) |
| ; RV32I-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s8) |
| ; RV32I-NEXT: $x10 = COPY [[ANYEXT]](s32) |
| ; RV32I-NEXT: $x11 = COPY [[ANYEXT1]](s32) |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @void_args_i8, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_void_args_i8 |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0 |
| ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1 |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[C]](s8) |
| ; RV64I-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[C1]](s8) |
| ; RV64I-NEXT: $x10 = COPY [[ANYEXT]](s64) |
| ; RV64I-NEXT: $x11 = COPY [[ANYEXT1]](s64) |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @void_args_i8, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| call void @void_args_i8(i8 0, i8 1) |
| ret void |
| } |
| |
| declare void @void_args_i8_zext(i8 zeroext, i8 zeroext) |
| |
| define void @test_call_void_args_i8_zext() { |
| |
| ; RV32I-LABEL: name: test_call_void_args_i8_zext |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0 |
| ; RV32I-NEXT: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1 |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[C]](s8) |
| ; RV32I-NEXT: [[ZEXT1:%[0-9]+]]:_(s32) = G_ZEXT [[C1]](s8) |
| ; RV32I-NEXT: $x10 = COPY [[ZEXT]](s32) |
| ; RV32I-NEXT: $x11 = COPY [[ZEXT1]](s32) |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @void_args_i8_zext, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_void_args_i8_zext |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0 |
| ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1 |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[C]](s8) |
| ; RV64I-NEXT: [[ZEXT1:%[0-9]+]]:_(s64) = G_ZEXT [[C1]](s8) |
| ; RV64I-NEXT: $x10 = COPY [[ZEXT]](s64) |
| ; RV64I-NEXT: $x11 = COPY [[ZEXT1]](s64) |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @void_args_i8_zext, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| call void @void_args_i8_zext(i8 zeroext 0, i8 zeroext 1) |
| ret void |
| } |
| |
| declare void @void_args_i16_sext(i16 signext, i16 signext) |
| |
| define void @test_call_void_args_i16_sext() { |
| |
| ; RV32I-LABEL: name: test_call_void_args_i16_sext |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 0 |
| ; RV32I-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 1 |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: [[SEXT:%[0-9]+]]:_(s32) = G_SEXT [[C]](s16) |
| ; RV32I-NEXT: [[SEXT1:%[0-9]+]]:_(s32) = G_SEXT [[C1]](s16) |
| ; RV32I-NEXT: $x10 = COPY [[SEXT]](s32) |
| ; RV32I-NEXT: $x11 = COPY [[SEXT1]](s32) |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @void_args_i16_sext, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_void_args_i16_sext |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 0 |
| ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 1 |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: [[SEXT:%[0-9]+]]:_(s64) = G_SEXT [[C]](s16) |
| ; RV64I-NEXT: [[SEXT1:%[0-9]+]]:_(s64) = G_SEXT [[C1]](s16) |
| ; RV64I-NEXT: $x10 = COPY [[SEXT]](s64) |
| ; RV64I-NEXT: $x11 = COPY [[SEXT1]](s64) |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @void_args_i16_sext, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| call void @void_args_i16_sext(i16 signext 0, i16 signext 1) |
| ret void |
| } |
| |
| declare void @void_args_i32(i32, i32) |
| |
| define void @test_call_void_args_i32() { |
| |
| ; RV32I-LABEL: name: test_call_void_args_i32 |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 |
| ; RV32I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: $x10 = COPY [[C]](s32) |
| ; RV32I-NEXT: $x11 = COPY [[C1]](s32) |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @void_args_i32, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_void_args_i32 |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 |
| ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[C]](s32) |
| ; RV64I-NEXT: [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[C1]](s32) |
| ; RV64I-NEXT: $x10 = COPY [[ANYEXT]](s64) |
| ; RV64I-NEXT: $x11 = COPY [[ANYEXT1]](s64) |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @void_args_i32, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| call void @void_args_i32(i32 0, i32 1) |
| ret void |
| } |
| |
| declare void @void_args_i64(i64, i64) |
| |
| define void @test_call_void_args_i64() { |
| |
| ; RV32I-LABEL: name: test_call_void_args_i64 |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 |
| ; RV32I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64) |
| ; RV32I-NEXT: [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64) |
| ; RV32I-NEXT: $x10 = COPY [[UV]](s32) |
| ; RV32I-NEXT: $x11 = COPY [[UV1]](s32) |
| ; RV32I-NEXT: $x12 = COPY [[UV2]](s32) |
| ; RV32I-NEXT: $x13 = COPY [[UV3]](s32) |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @void_args_i64, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_void_args_i64 |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 |
| ; RV64I-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: $x10 = COPY [[C]](s64) |
| ; RV64I-NEXT: $x11 = COPY [[C1]](s64) |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @void_args_i64, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| call void @void_args_i64(i64 0, i64 1) |
| ret void |
| } |
| |
| declare i8 @i8_noargs() |
| |
| define void @test_call_i8_noargs() { |
| |
| ; RV32I-LABEL: name: test_call_i8_noargs |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @i8_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10 |
| ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32) |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_i8_noargs |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @i8_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10 |
| ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s64) |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| %a = call i8 @i8_noargs() |
| ret void |
| } |
| |
| declare i16 @i16_noargs() |
| |
| define void @test_call_i16_noargs() { |
| |
| ; RV32I-LABEL: name: test_call_i16_noargs |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @i16_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10 |
| ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32) |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_i16_noargs |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @i16_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10 |
| ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s64) |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| %a = call i16 @i16_noargs() |
| ret void |
| } |
| |
| declare i32 @i32_noargs() |
| |
| define void @test_call_i32_noargs() { |
| |
| ; RV32I-LABEL: name: test_call_i32_noargs |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @i32_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_i32_noargs |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @i32_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10 |
| ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| %a = call i32 @i32_noargs() |
| ret void |
| } |
| |
| declare i64 @i64_noargs() |
| |
| define void @test_call_i64_noargs() { |
| |
| ; RV32I-LABEL: name: test_call_i64_noargs |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @i64_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10 |
| ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11 |
| ; RV32I-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32) |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_i64_noargs |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @i64_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10 |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| %a = call i64 @i64_noargs() |
| ret void |
| } |
| |
| declare ptr @ptr_noargs() |
| |
| define void @test_call_ptr_noargs() { |
| ; RV32I-LABEL: name: test_call_ptr_noargs |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @ptr_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_ptr_noargs |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @ptr_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10 |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| %a = call ptr @ptr_noargs() |
| ret void |
| } |
| |
| declare [2 x i32] @i32x2_noargs() |
| |
| define void @test_call_i32x2_noargs() { |
| ; RV32I-LABEL: name: test_call_i32x2_noargs |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @i32x2_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10 |
| ; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_i32x2_noargs |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @i32x2_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10 |
| ; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) |
| ; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11 |
| ; RV64I-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64) |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| %a = call [2 x i32] @i32x2_noargs() |
| ret void |
| } |
| |
| %struct.Foo = type { i32, i32, i32, i16, i8 } |
| @foo = global %struct.Foo { i32 1, i32 2, i32 3, i16 4, i8 5 }, align 4 |
| |
| declare void @void_sret_args(ptr sret(%struct.Foo) %f) |
| |
| define void @test_void_sret_args() { |
| ; RV32I-LABEL: name: test_void_sret_args |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @foo |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: $x10 = COPY [[GV]](p0) |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @void_sret_args, csr_ilp32_lp64, implicit-def $x1, implicit $x10 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_void_sret_args |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @foo |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: $x10 = COPY [[GV]](p0) |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @void_sret_args, csr_ilp32_lp64, implicit-def $x1, implicit $x10 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| call void @void_sret_args(ptr sret(%struct.Foo) @foo) |
| ret void |
| } |
| |
| declare external void @external_function() |
| |
| define void @test_call_external() { |
| ; RV32I-LABEL: name: test_call_external |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @external_function, csr_ilp32_lp64, implicit-def $x1 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_external |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @external_function, csr_ilp32_lp64, implicit-def $x1 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| call void @external_function() |
| ret void |
| } |
| |
| declare dso_local void @dso_local_function() |
| |
| define void @test_call_local() { |
| ; RV32I-LABEL: name: test_call_local |
| ; RV32I: bb.1.entry: |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoCALL target-flags(riscv-call) @dso_local_function, csr_ilp32_lp64, implicit-def $x1 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_call_local |
| ; RV64I: bb.1.entry: |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoCALL target-flags(riscv-call) @dso_local_function, csr_ilp32_lp64, implicit-def $x1 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoRET |
| entry: |
| call void @dso_local_function() |
| ret void |
| } |
| |
| define void @test_indirect_call(ptr %func) { |
| ; RV32I-LABEL: name: test_indirect_call |
| ; RV32I: bb.1 (%ir-block.0): |
| ; RV32I-NEXT: liveins: $x10 |
| ; RV32I-NEXT: {{ $}} |
| ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprjalr(p0) = COPY $x10 |
| ; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoCALLIndirect [[COPY]](p0), csr_ilp32_lp64, implicit-def $x1 |
| ; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV32I-NEXT: PseudoRET |
| ; |
| ; RV64I-LABEL: name: test_indirect_call |
| ; RV64I: bb.1 (%ir-block.0): |
| ; RV64I-NEXT: liveins: $x10 |
| ; RV64I-NEXT: {{ $}} |
| ; RV64I-NEXT: [[COPY:%[0-9]+]]:gprjalr(p0) = COPY $x10 |
| ; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoCALLIndirect [[COPY]](p0), csr_ilp32_lp64, implicit-def $x1 |
| ; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2 |
| ; RV64I-NEXT: PseudoRET |
| call void %func() |
| ret void |
| } |