diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp --- a/flang/lib/Optimizer/CodeGen/Target.cpp +++ b/flang/lib/Optimizer/CodeGen/Target.cpp @@ -334,6 +334,53 @@ }; } // namespace +//===----------------------------------------------------------------------===// +// RISCV64 linux target specifics. +//===----------------------------------------------------------------------===// + +namespace { +struct TargetRISCV64 : public GenericTarget { + using GenericTarget::GenericTarget; + + static constexpr int defaultWidth = 64; + + CodeGenSpecifics::Marshalling + complexArgumentType(mlir::Location loc, mlir::Type eleTy) const override { + CodeGenSpecifics::Marshalling marshal; + const auto *sem = &floatToSemantics(kindMap, eleTy); + if (sem == &llvm::APFloat::IEEEsingle() || + sem == &llvm::APFloat::IEEEdouble()) { + // A complex floating-point number, + // or a struct containing just one complex floating-point number, + // is passed as though it were a struct containing two floating-point reals. + mlir::TypeRange range = {eleTy, eleTy}; + marshal.emplace_back(mlir::TupleType::get(eleTy.getContext(), range), + AT{}); + } else { + TODO(loc, "complex for this precision"); + } + return marshal; + } + + CodeGenSpecifics::Marshalling + complexReturnType(mlir::Location loc, mlir::Type eleTy) const override { + CodeGenSpecifics::Marshalling marshal; + const auto *sem = &floatToSemantics(kindMap, eleTy); + if (sem == &llvm::APFloat::IEEEsingle() || + sem == &llvm::APFloat::IEEEdouble()) { + // Use a type that will be translated into LLVM as: + // { t, t } struct of 2 eleTy, byVal + mlir::TypeRange range = {eleTy, eleTy}; + marshal.emplace_back(mlir::TupleType::get(eleTy.getContext(), range), + AT{/*alignment=*/0, /*byval=*/true}); + } else { + TODO(loc, "complex for this precision"); + } + return marshal; + } +}; +} // namespace + // Instantiate the overloaded target instance based on the triple value. // TODO: Add other targets to this file as needed. std::unique_ptr @@ -409,6 +456,15 @@ std::move(kindMap)); } break; + case llvm::Triple::ArchType::riscv64: + switch (trp.getOS()) { + default: + break; + case llvm::Triple::OSType::Linux: + return std::make_unique(ctx, std::move(trp), + std::move(kindMap)); + } + break; } TODO(mlir::UnknownLoc::get(ctx), "target not implemented"); } diff --git a/flang/test/Fir/target-rewrite-complex.fir b/flang/test/Fir/target-rewrite-complex.fir --- a/flang/test/Fir/target-rewrite-complex.fir +++ b/flang/test/Fir/target-rewrite-complex.fir @@ -4,6 +4,7 @@ // RUN: fir-opt --target-rewrite="target=powerpc64le-unknown-linux-gnu" %s | FileCheck %s --check-prefix=PPC // RUN: fir-opt --target-rewrite="target=sparc64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=SPARCV9 // RUN: fir-opt --target-rewrite="target=sparcv9-sun-solaris2.11" %s | FileCheck %s --check-prefix=SPARCV9 +// RUN: fir-opt --target-rewrite="target=riscv64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=RISCV64 // Test that we rewrite the signature and body of a function that returns a // complex<4>. @@ -12,6 +13,7 @@ // AARCH64-LABEL: func @returncomplex4() -> tuple, !fir.real<4>> // PPC-LABEL: func @returncomplex4() -> tuple, !fir.real<4>> // SPARCV9-LABEL: func @returncomplex4() -> tuple, !fir.real<4>> +// RISCV64-LABEL: func @returncomplex4() -> tuple, !fir.real<4>> func.func @returncomplex4() -> !fir.complex<4> { // I32: fir.insert_value // I32: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value @@ -23,6 +25,8 @@ // PPC: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value // SPARCV9: fir.insert_value // SPARCV9: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value + // RISCV64: fir.insert_value + // RISCV64: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value %1 = fir.undefined !fir.complex<4> %2 = arith.constant 2.0 : f32 %3 = fir.convert %2 : (f32) -> !fir.real<4> @@ -57,6 +61,8 @@ // SPARCV9: fir.store [[VAL]] to [[ADDRC]] : !fir.ref> // SPARCV9: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRT]] : !fir.ref, !fir.real<4>>> // SPARCV9: return [[RES]] : tuple, !fir.real<4>> + // RISCV64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<4>> + // RISCV64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref, !fir.real<4>>>) -> !fir.ref> return %6 : !fir.complex<4> } @@ -68,6 +74,7 @@ // AARCH64-LABEL: func @returncomplex8() -> tuple, !fir.real<8>> // PPC-LABEL: func @returncomplex8() -> tuple, !fir.real<8>> // SPARCV9-LABEL: func @returncomplex8() -> tuple, !fir.real<8>> +// RISCV64-LABEL: func @returncomplex8() -> tuple, !fir.real<8>> func.func @returncomplex8() -> !fir.complex<8> { // I32: fir.insert_value // I32: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value {{.*}} @@ -79,6 +86,8 @@ // PPC: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value {{.*}} // SPARCV9: fir.insert_value // SPARCV9: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value {{.*}} + // RISCV64: fir.insert_value + // RISCV64: [[VAL:%[0-9A-Za-z]+]] = fir.insert_value {{.*}} %1 = fir.undefined !fir.complex<8> %2 = arith.constant 1.0 : f64 %3 = arith.constant -4.0 : f64 @@ -110,6 +119,11 @@ // SPARCV9: fir.store [[VAL]] to [[ADDRC]] : !fir.ref> // SPARCV9: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRT]] : !fir.ref, !fir.real<8>>> // SPARCV9: return [[RES]] : tuple, !fir.real<8>> + // RISCV64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<8>> + // RISCV64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref, !fir.real<8>>>) -> !fir.ref> + // RISCV64: fir.store [[VAL]] to [[ADDRC]] : !fir.ref> + // RISCV64: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRT]] : !fir.ref, !fir.real<8>>> + // RISCV64: return [[RES]] : tuple, !fir.real<8>> return %5 : !fir.complex<8> } @@ -119,6 +133,7 @@ // AARCH64-LABEL: func private @paramcomplex4(!fir.array<2x!fir.real<4>>) // PPC-LABEL: func private @paramcomplex4(!fir.real<4>, !fir.real<4>) // SPARCV9-LABEL: func private @paramcomplex4(!fir.real<4>, !fir.real<4>) +// RISCV64-LABEL: func private @paramcomplex4(tuple, !fir.real<4>>) func.func private @paramcomplex4(!fir.complex<4>) -> () // Test that we rewrite calls to functions that return or accept complex<4>. @@ -127,6 +142,7 @@ // AARCH64-LABEL: func @callcomplex4() // PPC-LABEL: func @callcomplex4() // SPARCV9-LABEL: func @callcomplex4() +// RISCV64-LABEL: func @callcomplex4() func.func @callcomplex4() { // I32: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> i64 @@ -134,6 +150,7 @@ // AARCH64: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> tuple, !fir.real<4>> // PPC: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> tuple, !fir.real<4>> // SPARCV9: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> tuple, !fir.real<4>> + // RISCV64: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex4() : () -> tuple, !fir.real<4>> %1 = fir.call @returncomplex4() : () -> !fir.complex<4> // I32: [[ADDRI64:%[0-9A-Za-z]+]] = fir.alloca i64 @@ -180,6 +197,16 @@ // SPARCV9: [[A:%[0-9A-Za-z]+]] = fir.extract_value [[V]], [0 : i32] : (!fir.complex<4>) -> !fir.real<4> // SPARCV9: [[B:%[0-9A-Za-z]+]] = fir.extract_value [[V]], [1 : i32] : (!fir.complex<4>) -> !fir.real<4> // SPARCV9: fir.call @paramcomplex4([[A]], [[B]]) : (!fir.real<4>, !fir.real<4>) -> () + + // RISCV64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<4>> + // RISCV64: fir.store [[RES]] to [[ADDRT]] : !fir.ref, !fir.real<4>>> + // RISCV64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref, !fir.real<4>>>) -> !fir.ref> + // RISCV64: [[V:%[0-9A-Za-z]+]] = fir.load [[ADDRC]] : !fir.ref> + // RISCV64: [[ADDRARR:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<4>> + // RISCV64: [[ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[ADDRARR]] : (!fir.ref, !fir.real<4>>>) -> !fir.ref> + // RISCV64: fir.store [[V]] to [[ADDRC2]] : !fir.ref> + // RISCV64: [[ARR:%[0-9A-Za-z]+]] = fir.load [[ADDRARR]] : !fir.ref, !fir.real<4>>> + // RISCV64: fir.call @paramcomplex4([[ARR]]) : (tuple, !fir.real<4>>) -> () fir.call @paramcomplex4(%1) : (!fir.complex<4>) -> () return } @@ -190,6 +217,7 @@ // AARCH64-LABEL: func private @paramcomplex8(!fir.array<2x!fir.real<8>>) // PPC-LABEL: func private @paramcomplex8(!fir.real<8>, !fir.real<8>) // SPARCV9-LABEL: func private @paramcomplex8(!fir.real<8>, !fir.real<8>) +// RISCV64-LABEL: func private @paramcomplex8(tuple, !fir.real<8>>) func.func private @paramcomplex8(!fir.complex<8>) -> () // Test that we rewrite calls to functions that return or accept complex<8>. @@ -198,6 +226,7 @@ // AARCH64-LABEL: func @callcomplex8() // PPC-LABEL: func @callcomplex8() // SPARCV9-LABEL: func @callcomplex8() +// RISCV64-LABEL: func @callcomplex8() func.func @callcomplex8() { // I32: [[RES:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<8>> // I32: fir.call @returncomplex8([[RES]]) : (!fir.ref, !fir.real<8>>>) -> () @@ -205,6 +234,7 @@ // AARCH64: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple, !fir.real<8>> // PPC: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple, !fir.real<8>> // SPARCV9: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple, !fir.real<8>> + // RISCV64: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple, !fir.real<8>> %1 = fir.call @returncomplex8() : () -> !fir.complex<8> // I32: [[RESC:%[0-9A-Za-z]+]] = fir.convert [[RES]] : (!fir.ref, !fir.real<8>>>) -> !fir.ref> @@ -248,6 +278,14 @@ // SPARCV9: [[B:%[0-9A-Za-z]+]] = fir.extract_value [[V]], [1 : i32] : (!fir.complex<8>) -> !fir.real<8> // SPARCV9: fir.call @paramcomplex8([[A]], [[B]]) : (!fir.real<8>, !fir.real<8>) -> () + // RISCV64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<8>> + // RISCV64: fir.store [[RES]] to [[ADDRT]] : !fir.ref, !fir.real<8>>> + // RISCV64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref, !fir.real<8>>>) -> !fir.ref> + // RISCV64: [[V:%[0-9A-Za-z]+]] = fir.load [[ADDRC]] : !fir.ref> + // RISCV64: [[A:%[0-9A-Za-z]+]] = fir.convert [[ADDRARR]] : (!fir.ref, !fir.real<8>>>) -> !fir.ref> + // RISCV64: [[B:%[0-9A-Za-z]+]] = fir.load [[ADDRARR]] : !fir.ref, !fir.real<8>>> + // RISCV64: fir.call @paramcomplex8([[ARR]]) : (tuple, !fir.real<8>>) -> () + fir.call @paramcomplex8(%1) : (!fir.complex<8>) -> () return } @@ -258,6 +296,7 @@ // AARCH64-LABEL: func private @calleemultipleparamscomplex4(!fir.array<2x!fir.real<4>>, !fir.array<2x!fir.real<4>>, !fir.array<2x!fir.real<4>>) // PPC-LABEL: func private @calleemultipleparamscomplex4(!fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>) // SPARCV9-LABEL: func private @calleemultipleparamscomplex4(!fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>) +// RISCV64-LABEL: func private @calleemultipleparamscomplex4(tuple, !fir.real<4>>, tuple, !fir.real<4>>, tuple, !fir.real<4>>) func.func private @calleemultipleparamscomplex4(!fir.complex<4>, !fir.complex<4>, !fir.complex<4>) -> () // I32-LABEL: func @multipleparamscomplex4 @@ -270,6 +309,8 @@ // PPC-SAME: ([[A1:%[0-9A-Za-z]+]]: !fir.real<4>, [[B1:%[0-9A-Za-z]+]]: !fir.real<4>, [[A2:%[0-9A-Za-z]+]]: !fir.real<4>, [[B2:%[0-9A-Za-z]+]]: !fir.real<4>, [[A3:%[0-9A-Za-z]+]]: !fir.real<4>, [[B3:%[0-9A-Za-z]+]]: !fir.real<4>) // SPARCV9-LABEL: func @multipleparamscomplex4 // SPARCV9-SAME: ([[A1:%[0-9A-Za-z]+]]: !fir.real<4>, [[B1:%[0-9A-Za-z]+]]: !fir.real<4>, [[A2:%[0-9A-Za-z]+]]: !fir.real<4>, [[B2:%[0-9A-Za-z]+]]: !fir.real<4>, [[A3:%[0-9A-Za-z]+]]: !fir.real<4>, [[B3:%[0-9A-Za-z]+]]: !fir.real<4>) +// RISCV64-LABEL: func @multipleparamscomplex4 +// RISCV64-SAME: ([[Z1:%[0-9A-Za-z]+]]: tuple, !fir.real<4>>, [[Z2:%[0-9A-Za-z]+]]: tuple, !fir.real<4>>, [[Z3:%[0-9A-Za-z]+]]: tuple, !fir.real<4>>) func.func @multipleparamscomplex4(%z1 : !fir.complex<4>, %z2 : !fir.complex<4>, %z3 : !fir.complex<4>) { // I32-DAG: [[Z1_ADDR:%[0-9A-Za-z]+]] = fir.convert [[Z1]] : (!fir.ref, !fir.real<4>>>) -> !fir.ref> // I32-DAG: [[Z1_VAL:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDR]] : !fir.ref> @@ -384,6 +425,33 @@ // SPARCV9: fir.call @calleemultipleparamscomplex4([[A1_EXTR]], [[B1_EXTR]], [[A2_EXTR]], [[B2_EXTR]], [[A3_EXTR]], [[B3_EXTR]]) : (!fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>, !fir.real<4>) -> () + // RISCV64-DAG: [[Z3_ADDR:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<4>> + // RISCV64-DAG: fir.store [[Z3]] to [[Z3_ADDR]] : !fir.ref, !fir.real<4>>> + // RISCV64-DAG: [[Z3_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z3_ADDR]] : (!fir.ref, !fir.real<4>>>) -> !fir.ref> + // RISCV64-DAG: [[Z3_VAL:%[0-9A-Za-z]+]] = fir.load [[Z3_ADDRC]] : !fir.ref> + // RISCV64-DAG: [[Z2_ADDR:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<4>> + // RISCV64-DAG: fir.store [[Z2]] to [[Z2_ADDR]] : !fir.ref, !fir.real<4>>> + // RISCV64-DAG: [[Z2_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDR]] : (!fir.ref, !fir.real<4>>>) -> !fir.ref> + // RISCV64-DAG: [[Z2_VAL:%[0-9A-Za-z]+]] = fir.load [[Z2_ADDRC]] : !fir.ref> + // RISCV64-DAG: [[Z1_ADDR:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<4>> + // RISCV64-DAG: fir.store [[Z1]] to [[Z1_ADDR]] : !fir.ref, !fir.real<4>>> + // RISCV64-DAG: [[Z1_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z1_ADDR]] : (!fir.ref, !fir.real<4>>>) -> !fir.ref> + // RISCV64-DAG: [[Z1_VAL:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDRC]] : !fir.ref> + + // RISCV64-DAG: [[Z1_ADDRV:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<4>> + // RISCV64-DAG: [[Z1_ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[Z1_ADDRV]] : (!fir.ref, !fir.real<4>>>) -> !fir.ref> + // RISCV64-DAG: fir.store [[Z1_VAL]] to [[Z1_ADDRC2]] : !fir.ref> + // RISCV64-DAG: [[Z1_RELOADED:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDRV]] : !fir.ref, !fir.real<4>>> + // RISCV64-DAG: [[Z2_ADDRV:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<4>> + // RISCV64-DAG: [[Z2_ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDRV]] : (!fir.ref, !fir.real<4>>>) -> !fir.ref> + // RISCV64-DAG: fir.store [[Z2_VAL]] to [[Z2_ADDRC2]] : !fir.ref> + // RISCV64-DAG: [[Z2_RELOADED:%[0-9A-Za-z]+]] = fir.load [[Z2_ADDRV]] : !fir.ref, !fir.real<4>>> + // RISCV64-DAG: [[Z3_ADDRV:%[0-9A-Za-z]+]] = fir.alloca tuple, !fir.real<4>> + // RISCV64-DAG: [[Z3_ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[Z3_ADDRV]] : (!fir.ref, !fir.real<4>>>) -> !fir.ref> + // RISCV64-DAG: fir.store [[Z3_VAL]] to [[Z3_ADDRC2]] : !fir.ref> + // RISCV64-DAG: [[Z3_RELOADED:%[0-9A-Za-z]+]] = fir.load [[Z3_ADDRV]] : !fir.ref, !fir.real<4>>> + + // RISCV64: fir.call @calleemultipleparamscomplex4([[Z1_RELOADED]], [[Z2_RELOADED]], [[Z3_RELOADED]]) : (tuple, !fir.real<4>>, tuple, !fir.real<4>>, tuple, !fir.real<4>>) -> () fir.call @calleemultipleparamscomplex4(%z1, %z2, %z3) : (!fir.complex<4>, !fir.complex<4>, !fir.complex<4>) -> () return } @@ -406,6 +474,9 @@ // SPARCV9-LABEL: func private @mlircomplexf32 // SPARCV9-SAME: ([[A1:%[0-9A-Za-z]+]]: f32, [[B1:%[0-9A-Za-z]+]]: f32, [[A2:%[0-9A-Za-z]+]]: f32, [[B2:%[0-9A-Za-z]+]]: f32) // SPARCV9-SAME: -> tuple +// RISCV64-LABEL: func private @mlircomplexf32 +// RISCV64-SAME: ([[Z1:%[0-9A-Za-z]+]]: tuple, [[Z2:%[0-9A-Za-z]+]]: tuple) +// RISCV64-SAME: -> tuple func.func private @mlircomplexf32(%z1: complex, %z2: complex) -> complex { // I32-DAG: [[Z1_ADDR:%[0-9A-Za-z]+]] = fir.convert [[Z1]] : (!fir.ref>) -> !fir.ref> @@ -489,6 +560,26 @@ // SPARCV9-DAG: [[B2_EXTR:%[0-9A-Za-z]+]] = fir.extract_value [[Z2]], [1 : i32] : (complex) -> f32 // SPARCV9: [[VAL:%[0-9A-Za-z]+]] = fir.call @mlircomplexf32([[A1_EXTR]], [[B1_EXTR]], [[A2_EXTR]], [[B2_EXTR]]) : (f32, f32, f32, f32) -> tuple + + // RISCV64-DAG: [[Z2_ADDR:%[0-9A-Za-z]+]] = fir.alloca tuple + // RISCV64-DAG: fir.store [[Z2]] to [[Z2_ADDR]] : !fir.ref> + // RISCV64-DAG: [[Z2_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDR]] : (!fir.ref>) -> !fir.ref> + // RISCV64-DAG: [[Z2_VAL:%[0-9A-Za-z]+]] = fir.load [[Z2_ADDRC]] : !fir.ref> + // RISCV64-DAG: [[Z1_ADDR:%[0-9A-Za-z]+]] = fir.alloca tuple + // RISCV64-DAG: fir.store [[Z1]] to [[Z1_ADDR]] : !fir.ref> + // RISCV64-DAG: [[Z1_ADDRC:%[0-9A-Za-z]+]] = fir.convert [[Z1_ADDR]] : (!fir.ref>) -> !fir.ref> + // RISCV64-DAG: [[Z1_VAL:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDRC]] : !fir.ref> + + // RISCV64-DAG: [[Z1_ADDRV:%[0-9A-Za-z]+]] = fir.alloca tuple + // RISCV64-DAG: [[Z1_ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[Z1_ADDRV]] : (!fir.ref>) -> !fir.ref> + // RISCV64-DAG: fir.store [[Z1_VAL]] to [[Z1_ADDRC2]] : !fir.ref> + // RISCV64-DAG: [[Z1_RELOADED:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDRV]] : !fir.ref> + // RISCV64-DAG: [[Z2_ADDRV:%[0-9A-Za-z]+]] = fir.alloca tuple + // RISCV64-DAG: [[Z2_ADDRC2:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDRV]] : (!fir.ref>) -> !fir.ref> + // RISCV64-DAG: fir.store [[Z2_VAL]] to [[Z2_ADDRC2]] : !fir.ref> + // RISCV64-DAG: [[Z2_RELOADED:%[0-9A-Za-z]+]] = fir.load [[Z2_ADDRV]] : !fir.ref> + + // RISCV64: [[VAL:%[0-9A-Za-z]+]] = fir.call @mlircomplexf32([[Z1_RELOADED]], [[Z2_RELOADED]]) : (tuple, tuple) -> tuple %0 = fir.call @mlircomplexf32(%z1, %z2) : (complex, complex) -> complex // I32: [[ADDRI64:%[0-9A-Za-z]+]] = fir.alloca i64 @@ -540,6 +631,16 @@ // SPARCV9: fir.store [[V]] to [[ADDRC_2]] : !fir.ref> // SPARCV9: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRT_2]] : !fir.ref> // SPARCV9: return [[RES]] : tuple + + // RISCV64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple + // RISCV64: fir.store [[VAL]] to [[ADDRT]] : !fir.ref> + // RISCV64: [[ADDRC:%[0-9A-Za-z]+]] = fir.convert [[ADDRT]] : (!fir.ref>) -> !fir.ref> + // RISCV64: [[V:%[0-9A-Za-z]+]] = fir.load [[ADDRC]] : !fir.ref> + // RISCV64: [[ADDRT_2:%[0-9A-Za-z]+]] = fir.alloca tuple + // RISCV64: [[ADDRC_2:%[0-9A-Za-z]+]] = fir.convert [[ADDRT_2]] : (!fir.ref>) -> !fir.ref> + // RISCV64: fir.store [[V]] to [[ADDRC_2]] : !fir.ref> + // RISCV64: [[RES:%[0-9A-Za-z]+]] = fir.load [[ADDRT_2]] : !fir.ref> + // RISCV64: return [[RES]] : tuple return %0 : complex } @@ -549,11 +650,13 @@ // AARCH64-LABEL: func @addrof() // PPC-LABEL: func @addrof() // SPARCV9-LABEL: func @addrof() +// RISCV64-LABEL: func @addrof() func.func @addrof() { // I32: {{%.*}} = fir.address_of(@returncomplex4) : () -> i64 // X64: {{%.*}} = fir.address_of(@returncomplex4) : () -> !fir.vector<2:!fir.real<4>> // AARCH64: {{%.*}} = fir.address_of(@returncomplex4) : () -> tuple, !fir.real<4>> // PPC: {{%.*}} = fir.address_of(@returncomplex4) : () -> tuple, !fir.real<4>> + // RISCV64: {{%.*}} = fir.address_of(@returncomplex4) : () -> tuple, !fir.real<4>> %r = fir.address_of(@returncomplex4) : () -> !fir.complex<4> // I32: {{%.*}} = fir.address_of(@paramcomplex4) : (!fir.ref, !fir.real<4>>>) -> () @@ -561,6 +664,7 @@ // AARCH64: {{%.*}} = fir.address_of(@paramcomplex4) : (!fir.array<2x!fir.real<4>>) -> () // PPC: {{%.*}} = fir.address_of(@paramcomplex4) : (!fir.real<4>, !fir.real<4>) -> () // SPARCV9: {{%.*}} = fir.address_of(@paramcomplex4) : (!fir.real<4>, !fir.real<4>) -> () + // RISCV64: {{%.*}} = fir.address_of(@paramcomplex4) : (tuple, !fir.real<4>>) -> () %p = fir.address_of(@paramcomplex4) : (!fir.complex<4>) -> () return }