[flang-commits] [flang] 15e335f - [flang] also set llvm ABI argument attributes on direct calls (#130736)
via flang-commits
flang-commits at lists.llvm.org
Wed Mar 12 01:55:08 PDT 2025
Author: jeanPerier
Date: 2025-03-12T09:55:05+01:00
New Revision: 15e335f04fba3d16e195c055952649f8852e3b35
URL: https://github.com/llvm/llvm-project/commit/15e335f04fba3d16e195c055952649f8852e3b35
DIFF: https://github.com/llvm/llvm-project/commit/15e335f04fba3d16e195c055952649f8852e3b35.diff
LOG: [flang] also set llvm ABI argument attributes on direct calls (#130736)
So far, flang was not setting argument attributes on direct calls
assuming that putting them on the function operation was enough.
It was clarified in
https://github.com/llvm/llvm-project/commit/38565da5259729898c2a552d54b72f3314241734
that they must be set on both call and functions, even for direct calls.
Crashes have been observed because of the lack of the attribute when
compiling `abs(x)` at `O2` and above on X86-64 for complex(16).
Added:
Modified:
flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
flang/test/Fir/CUDA/cuda-target-rewrite.mlir
flang/test/Fir/struct-passing-return-loongarch64-bystack.fir
flang/test/Fir/struct-passing-x86-64-byval.fir
flang/test/Fir/struct-passing-x86-64-one-field-inreg.fir
flang/test/Fir/struct-passing-x86-64-several-fields-inreg.fir
flang/test/Fir/struct-return-aarch64.fir
flang/test/Fir/struct-return-loongarch64-byreg.fir
flang/test/Fir/struct-return-powerpc64-aix.fir
flang/test/Fir/struct-return-ppc64le.fir
flang/test/Fir/struct-return-x86-64.fir
flang/test/Fir/target-rewrite-complex-10-x86.fir
flang/test/Fir/target-rewrite-complex.fir
flang/test/Fir/target-rewrite-complex16.fir
flang/test/Fir/target-rewrite-indirect-calls.fir
flang/test/Fir/target-rewrite-integer-loongarch64.fir
flang/test/Fir/target.fir
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
index 5c9da0321bcc4..43ed60fc0c292 100644
--- a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
@@ -541,37 +541,37 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
callOp.getContext(),
mlir::TypeRange{newInTypes}.drop_front(dropFront), newResTys));
newCall = rewriter->create<fir::CallOp>(loc, newResTys, newOpers);
- // Set ABI argument attributes on call operation since they are not
- // accessible via a FuncOp in indirect calls.
- if (hasByValOrSRetArgs(newInTyAndAttrs)) {
- llvm::SmallVector<mlir::Attribute> argAttrsArray;
- for (const auto &arg :
- llvm::ArrayRef<fir::CodeGenSpecifics::TypeAndAttr>(
- newInTyAndAttrs)
- .drop_front(dropFront)) {
- mlir::NamedAttrList argAttrs;
- const auto &attr = std::get<fir::CodeGenSpecifics::Attributes>(arg);
- if (attr.isByVal()) {
- mlir::Type elemType =
- fir::dyn_cast_ptrOrBoxEleTy(std::get<mlir::Type>(arg));
- argAttrs.set(mlir::LLVM::LLVMDialect::getByValAttrName(),
- mlir::TypeAttr::get(elemType));
- } else if (attr.isSRet()) {
- mlir::Type elemType =
- fir::dyn_cast_ptrOrBoxEleTy(std::get<mlir::Type>(arg));
- argAttrs.set(mlir::LLVM::LLVMDialect::getStructRetAttrName(),
- mlir::TypeAttr::get(elemType));
- if (auto align = attr.getAlignment()) {
- argAttrs.set(mlir::LLVM::LLVMDialect::getAlignAttrName(),
- rewriter->getIntegerAttr(
- rewriter->getIntegerType(32), align));
- }
- }
- argAttrsArray.emplace_back(
- argAttrs.getDictionary(rewriter->getContext()));
+ }
+ // Always set ABI argument attributes on call operations, even when
+ // direct, as required by
+ // https://llvm.org/docs/LangRef.html#parameter-attributes.
+ if (hasByValOrSRetArgs(newInTyAndAttrs)) {
+ llvm::SmallVector<mlir::Attribute> argAttrsArray;
+ for (const auto &arg :
+ llvm::ArrayRef<fir::CodeGenSpecifics::TypeAndAttr>(newInTyAndAttrs)
+ .drop_front(dropFront)) {
+ mlir::NamedAttrList argAttrs;
+ const auto &attr = std::get<fir::CodeGenSpecifics::Attributes>(arg);
+ if (attr.isByVal()) {
+ mlir::Type elemType =
+ fir::dyn_cast_ptrOrBoxEleTy(std::get<mlir::Type>(arg));
+ argAttrs.set(mlir::LLVM::LLVMDialect::getByValAttrName(),
+ mlir::TypeAttr::get(elemType));
+ } else if (attr.isSRet()) {
+ mlir::Type elemType =
+ fir::dyn_cast_ptrOrBoxEleTy(std::get<mlir::Type>(arg));
+ argAttrs.set(mlir::LLVM::LLVMDialect::getStructRetAttrName(),
+ mlir::TypeAttr::get(elemType));
+ }
+ if (auto align = attr.getAlignment()) {
+ argAttrs.set(
+ mlir::LLVM::LLVMDialect::getAlignAttrName(),
+ rewriter->getIntegerAttr(rewriter->getIntegerType(32), align));
}
- newCall.setArgAttrsAttr(rewriter->getArrayAttr(argAttrsArray));
+ argAttrsArray.emplace_back(
+ argAttrs.getDictionary(rewriter->getContext()));
}
+ newCall.setArgAttrsAttr(rewriter->getArrayAttr(argAttrsArray));
}
LLVM_DEBUG(llvm::dbgs() << "replacing call with " << newCall << '\n');
if (wrap)
diff --git a/flang/test/Fir/CUDA/cuda-target-rewrite.mlir b/flang/test/Fir/CUDA/cuda-target-rewrite.mlir
index 0e7534e06c89c..831b5a0048008 100644
--- a/flang/test/Fir/CUDA/cuda-target-rewrite.mlir
+++ b/flang/test/Fir/CUDA/cuda-target-rewrite.mlir
@@ -1,6 +1,7 @@
-// REQUIRES: x86-registered-target
// RUN: fir-opt --split-input-file --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s
+module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+
gpu.module @testmod {
gpu.func @_QPvcpowdk(%arg0: !fir.ref<complex<f64>> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "a"}) attributes {cuf.proc_attr = #cuf.cuda_proc<global>} {
%0 = fir.alloca i64
@@ -15,22 +16,25 @@ gpu.module @testmod {
// CHECK-LABEL: gpu.func @_QPvcpowdk
// CHECK: %{{.*}} = fir.call @_FortranAzpowk(%{{.*}}, %{{.*}}, %{{.*}}) : (f64, f64, i64) -> tuple<f64, f64>
// CHECK: func.func private @_FortranAzpowk(f64, f64, i64) -> tuple<f64, f64> attributes {fir.bindc_name = "_FortranAzpowk", fir.runtime}
+}
// -----
+module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+
gpu.module @testmod {
gpu.func @_QPtest(%arg0: complex<f64>) -> (complex<f64>) {
gpu.return %arg0 : complex<f64>
}
}
+}
// CHECK-LABEL: gpu.func @_QPtest
// CHECK-SAME: (%arg0: f64, %arg1: f64) -> tuple<f64, f64> {
// CHECK: gpu.return %{{.*}} : tuple<f64, f64>
-
// -----
-module attributes {gpu.container_module} {
+module attributes {gpu.container_module, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
gpu.module @testmod {
gpu.func @_QPtest(%arg0: complex<f64>) -> () kernel {
diff --git a/flang/test/Fir/struct-passing-return-loongarch64-bystack.fir b/flang/test/Fir/struct-passing-return-loongarch64-bystack.fir
index 5041a39e69798..91ac345d2d7af 100644
--- a/flang/test/Fir/struct-passing-return-loongarch64-bystack.fir
+++ b/flang/test/Fir/struct-passing-return-loongarch64-bystack.fir
@@ -1,7 +1,6 @@
/// Test LoongArch64 ABI rewrite of struct passed and returned by value (BIND(C), VALUE derived types).
/// This test test cases where the struct must be passed or returned on the stack.
-// REQUIRES: loongarch-registered-target
// RUN: tco --target=loongarch64-unknown-linux-gnu %s | FileCheck %s
!ty_int_toobig = !fir.type<int_toobig{i:!fir.array<5xi32>}>
diff --git a/flang/test/Fir/struct-passing-x86-64-byval.fir b/flang/test/Fir/struct-passing-x86-64-byval.fir
index 13cf52de581f7..8451c26095226 100644
--- a/flang/test/Fir/struct-passing-x86-64-byval.fir
+++ b/flang/test/Fir/struct-passing-x86-64-byval.fir
@@ -1,7 +1,6 @@
// Test X86-64 ABI rewrite of struct passed by value (BIND(C), VALUE derived types).
// This test test cases where the struct must be passed on the stack according
// to the System V ABI.
-// REQUIRES: x86-registered-target
// RUN: tco --target=x86_64-unknown-linux-gnu %s | FileCheck %s
module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
diff --git a/flang/test/Fir/struct-passing-x86-64-one-field-inreg.fir b/flang/test/Fir/struct-passing-x86-64-one-field-inreg.fir
index e37e8dd4481d0..7feb698e0d5c5 100644
--- a/flang/test/Fir/struct-passing-x86-64-one-field-inreg.fir
+++ b/flang/test/Fir/struct-passing-x86-64-one-field-inreg.fir
@@ -1,6 +1,5 @@
// Test X86-64 passing ABI of struct in registers for the simple case
// where the struct has a single intrinsic component that is not a complex.
-// REQUIRES: x86-registered-target
// RUN: fir-opt -target-rewrite="target=x86_64-unknown-linux-gnu" %s -o - | FileCheck %s
module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
diff --git a/flang/test/Fir/struct-passing-x86-64-several-fields-inreg.fir b/flang/test/Fir/struct-passing-x86-64-several-fields-inreg.fir
index 9a0a41e1da542..afc8c2de85019 100644
--- a/flang/test/Fir/struct-passing-x86-64-several-fields-inreg.fir
+++ b/flang/test/Fir/struct-passing-x86-64-several-fields-inreg.fir
@@ -1,6 +1,5 @@
// Test X86-64 passing ABI of struct in registers for the cases where the
// struct has more than one field.
-// REQUIRES: x86-registered-target
// RUN: fir-opt -target-rewrite="target=x86_64-unknown-linux-gnu" %s -o - | FileCheck %s
diff --git a/flang/test/Fir/struct-return-aarch64.fir b/flang/test/Fir/struct-return-aarch64.fir
index 8b75c2cac7b6b..57be5a9828284 100644
--- a/flang/test/Fir/struct-return-aarch64.fir
+++ b/flang/test/Fir/struct-return-aarch64.fir
@@ -125,7 +125,7 @@ func.func private @test_too_big() -> !too_big
func.func @test_call_too_big(%arg0 : !fir.ref<!too_big>) {
// CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
// CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t7{x:i64,y:i64,z:i64}>
- // CHECK: fir.call @test_too_big(%[[ARG]]) : (!fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>) -> ()
+ // CHECK: fir.call @test_too_big(%[[ARG]]) : (!fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t7{x:i64,y:i64,z:i64}>}) -> ()
// CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>) -> !fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>
// CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>
// CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
@@ -145,7 +145,7 @@ func.func private @test_too_big_hfa() -> !too_big_hfa
func.func @test_call_too_big_hfa(%arg0 : !fir.ref<!too_big_hfa>) {
// CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
// CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t8{i:!fir.array<5xf32>}>
- // CHECK: fir.call @test_too_big_hfa(%[[ARG]]) : (!fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>) -> ()
+ // CHECK: fir.call @test_too_big_hfa(%[[ARG]]) : (!fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t8{i:!fir.array<5xf32>}>}) -> ()
// CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>) -> !fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>
// CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>
// CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
diff --git a/flang/test/Fir/struct-return-loongarch64-byreg.fir b/flang/test/Fir/struct-return-loongarch64-byreg.fir
index eb3d4d50d8866..baf9c74d6231a 100644
--- a/flang/test/Fir/struct-return-loongarch64-byreg.fir
+++ b/flang/test/Fir/struct-return-loongarch64-byreg.fir
@@ -7,7 +7,6 @@
/// only the first example in each category checks the entire invocation process,
/// while the other examples only check the signatures.
-// REQUIRES: loongarch-registered-target
// RUN: fir-opt --split-input-file --target-rewrite="target=loongarch64-unknown-linux-gnu" %s | FileCheck %s
diff --git a/flang/test/Fir/struct-return-powerpc64-aix.fir b/flang/test/Fir/struct-return-powerpc64-aix.fir
index 3058ef6b7e965..5037ffca0c79d 100644
--- a/flang/test/Fir/struct-return-powerpc64-aix.fir
+++ b/flang/test/Fir/struct-return-powerpc64-aix.fir
@@ -15,7 +15,7 @@ func.func @test_call_t1(%arg0 : !fir.ref<!fir.type<t1<{c:!fir.char<1>}>>>) {
return
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t1<{c:!fir.char<1>}>>
- //CHECK: fir.call @test_t1(%[[ARG]]) : (!fir.ref<!fir.type<t1<{c:!fir.char<1>}>>>) -> ()
+ //CHECK: fir.call @test_t1(%[[ARG]]) : (!fir.ref<!fir.type<t1<{c:!fir.char<1>}>>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t1<{c:!fir.char<1>}>>}) -> ()
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t1<{c:!fir.char<1>}>>>) -> !fir.ref<!fir.type<t1<{c:!fir.char<1>}>>>
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t1<{c:!fir.char<1>}>>>
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr
@@ -34,7 +34,7 @@ func.func @test_call_t2(%arg0 : !fir.ref<!fir.type<t2<{i:i32}>>>) {
return
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t2<{i:i32}>>
- //CHECK: fir.call @test_t2(%[[ARG]]) : (!fir.ref<!fir.type<t2<{i:i32}>>>) -> ()
+ //CHECK: fir.call @test_t2(%[[ARG]]) : (!fir.ref<!fir.type<t2<{i:i32}>>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t2<{i:i32}>>}) -> ()
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t2<{i:i32}>>>) -> !fir.ref<!fir.type<t2<{i:i32}>>>
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t2<{i:i32}>>>
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr
@@ -53,7 +53,7 @@ func.func @test_call_t3(%arg0 : !fir.ref<!fir.type<t3<{r1:f32,r2:f32,r3:f32}>>>)
return
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t3<{r1:f32,r2:f32,r3:f32}>>
- //CHECK: fir.call @test_t3(%[[ARG]]) : (!fir.ref<!fir.type<t3<{r1:f32,r2:f32,r3:f32}>>>) -> ()
+ //CHECK: fir.call @test_t3(%[[ARG]]) : (!fir.ref<!fir.type<t3<{r1:f32,r2:f32,r3:f32}>>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t3<{r1:f32,r2:f32,r3:f32}>>}) -> ()
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t3<{r1:f32,r2:f32,r3:f32}>>>) -> !fir.ref<!fir.type<t3<{r1:f32,r2:f32,r3:f32}>>>
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t3<{r1:f32,r2:f32,r3:f32}>>>
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr
@@ -72,7 +72,7 @@ func.func @test_call_t4(%arg0 : !fir.ref<!fir.type<t4<{r:!fir.array<8xf32>}>>>)
return
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t4<{r:!fir.array<8xf32>}>>
- //CHECK: fir.call @test_t4(%[[ARG]]) : (!fir.ref<!fir.type<t4<{r:!fir.array<8xf32>}>>>) -> ()
+ //CHECK: fir.call @test_t4(%[[ARG]]) : (!fir.ref<!fir.type<t4<{r:!fir.array<8xf32>}>>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t4<{r:!fir.array<8xf32>}>>}) -> ()
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t4<{r:!fir.array<8xf32>}>>>) -> !fir.ref<!fir.type<t4<{r:!fir.array<8xf32>}>>>
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t4<{r:!fir.array<8xf32>}>>>
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr
@@ -91,7 +91,7 @@ func.func @test_call_t5(%arg0 : !fir.ref<!fir.type<t5<{c:!fir.char<1>,r:f32,i:i6
return
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t5<{c:!fir.char<1>,r:f32,i:i64}>>
- //CHECK: fir.call @test_t5(%[[ARG]]) : (!fir.ref<!fir.type<t5<{c:!fir.char<1>,r:f32,i:i64}>>>) -> ()
+ //CHECK: fir.call @test_t5(%[[ARG]]) : (!fir.ref<!fir.type<t5<{c:!fir.char<1>,r:f32,i:i64}>>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t5<{c:!fir.char<1>,r:f32,i:i64}>>}) -> ()
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t5<{c:!fir.char<1>,r:f32,i:i64}>>>) -> !fir.ref<!fir.type<t5<{c:!fir.char<1>,r:f32,i:i64}>>>
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t5<{c:!fir.char<1>,r:f32,i:i64}>>>
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr
diff --git a/flang/test/Fir/struct-return-ppc64le.fir b/flang/test/Fir/struct-return-ppc64le.fir
index a5906280a0ef8..a19f8885ee0c5 100644
--- a/flang/test/Fir/struct-return-ppc64le.fir
+++ b/flang/test/Fir/struct-return-ppc64le.fir
@@ -15,7 +15,7 @@ func.func @test_call_t1(%arg0 : !fir.ref<!fir.type<t1{c:!fir.char<1>}>>) {
return
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t1{c:!fir.char<1>}>
- //CHECK: fir.call @test_t1(%[[ARG]]) : (!fir.ref<!fir.type<t1{c:!fir.char<1>}>>) -> ()
+ //CHECK: fir.call @test_t1(%[[ARG]]) : (!fir.ref<!fir.type<t1{c:!fir.char<1>}>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t1{c:!fir.char<1>}>}) -> ()
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t1{c:!fir.char<1>}>>) -> !fir.ref<!fir.type<t1{c:!fir.char<1>}>>
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t1{c:!fir.char<1>}>>
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr
@@ -34,7 +34,7 @@ func.func @test_call_t2(%arg0 : !fir.ref<!fir.type<t2{i:i32}>>) {
return
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t2{i:i32}>
- //CHECK: fir.call @test_t2(%[[ARG]]) : (!fir.ref<!fir.type<t2{i:i32}>>) -> ()
+ //CHECK: fir.call @test_t2(%[[ARG]]) : (!fir.ref<!fir.type<t2{i:i32}>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t2{i:i32}>}) -> ()
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t2{i:i32}>>) -> !fir.ref<!fir.type<t2{i:i32}>>
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t2{i:i32}>>
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr
@@ -73,7 +73,7 @@ func.func @test_call_t4(%arg0 : !fir.ref<!fir.type<t4{r:!fir.array<9xf32>}>>) {
return
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t4{r:!fir.array<9xf32>}>
- //CHECK: fir.call @test_t4(%[[ARG]]) : (!fir.ref<!fir.type<t4{r:!fir.array<9xf32>}>>) -> ()
+ //CHECK: fir.call @test_t4(%[[ARG]]) : (!fir.ref<!fir.type<t4{r:!fir.array<9xf32>}>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t4{r:!fir.array<9xf32>}>}) -> ()
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t4{r:!fir.array<9xf32>}>>) -> !fir.ref<!fir.type<t4{r:!fir.array<9xf32>}>>
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t4{r:!fir.array<9xf32>}>>
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr
@@ -92,7 +92,7 @@ func.func @test_call_t5(%arg0 : !fir.ref<!fir.type<t5{c:!fir.char<1>,r:f32,i:i64
return
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t5{c:!fir.char<1>,r:f32,i:i64}>
- //CHECK: fir.call @test_t5(%[[ARG]]) : (!fir.ref<!fir.type<t5{c:!fir.char<1>,r:f32,i:i64}>>) -> ()
+ //CHECK: fir.call @test_t5(%[[ARG]]) : (!fir.ref<!fir.type<t5{c:!fir.char<1>,r:f32,i:i64}>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t5{c:!fir.char<1>,r:f32,i:i64}>}) -> ()
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t5{c:!fir.char<1>,r:f32,i:i64}>>) -> !fir.ref<!fir.type<t5{c:!fir.char<1>,r:f32,i:i64}>>
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t5{c:!fir.char<1>,r:f32,i:i64}>>
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr
diff --git a/flang/test/Fir/struct-return-x86-64.fir b/flang/test/Fir/struct-return-x86-64.fir
index f4c2add69ff7e..5d1e6129d8f69 100644
--- a/flang/test/Fir/struct-return-x86-64.fir
+++ b/flang/test/Fir/struct-return-x86-64.fir
@@ -1,5 +1,4 @@
// Test X86-64 ABI rewrite of struct returned by value (BIND(C), VALUE derived types).
-// REQUIRES: x86-registered-target
// RUN: fir-opt --target-rewrite %s | FileCheck %s
!fits_in_reg = !fir.type<t1{i:f32,j:i32,k:f32}>
@@ -86,7 +85,7 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>) {
// CHECK: %[[VAL_1:.*]] = llvm.intr.stacksave : !llvm.ptr
// CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<t2{i:!fir.array<5xf32>}>
-// CHECK: fir.call @test_sret(%[[VAL_2]]) : (!fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>) -> ()
+// CHECK: fir.call @test_sret(%[[VAL_2]]) : (!fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t2{i:!fir.array<5xf32>}>}) -> ()
// CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>) -> !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>
// CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>
// CHECK: llvm.intr.stackrestore %[[VAL_1]] : !llvm.ptr
diff --git a/flang/test/Fir/target-rewrite-complex-10-x86.fir b/flang/test/Fir/target-rewrite-complex-10-x86.fir
index a6dd178cfe70a..6404b4f766d39 100644
--- a/flang/test/Fir/target-rewrite-complex-10-x86.fir
+++ b/flang/test/Fir/target-rewrite-complex-10-x86.fir
@@ -1,8 +1,9 @@
// Test COMPLEX(10) passing and returning on X86
-// REQUIRES: x86-registered-target
// RUN: fir-opt --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=AMD64
// RUN: tco -target="x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=AMD64_LLVM
+module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+
func.func @returncomplex10() -> complex<f80> {
%1 = fir.zero_bits complex<f80>
return %1 : complex<f80>
@@ -30,3 +31,4 @@ func.func @takecomplex10(%z: complex<f80>) {
// AMD64: fir.store %[[VAL_2]] to %[[VAL_3]] : !fir.ref<complex<f80>>
// AMD64_LLVM: define void @takecomplex10(ptr byval({ x86_fp80, x86_fp80 }) align 16 captures(none) %0)
+}
diff --git a/flang/test/Fir/target-rewrite-complex.fir b/flang/test/Fir/target-rewrite-complex.fir
index e697abb6e3ab3..405b14031f0c5 100644
--- a/flang/test/Fir/target-rewrite-complex.fir
+++ b/flang/test/Fir/target-rewrite-complex.fir
@@ -235,7 +235,7 @@ func.func @callcomplex4(%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i3
// I32: [[ADDRC2:%[0-9A-Za-z]+]] = fir.alloca complex<f32>
// I32: fir.store [[C]] to [[ADDRC2]] : !fir.ref<complex<f32>>
// I32: [[T:%[0-9A-Za-z]+]] = fir.convert [[ADDRC2]] : (!fir.ref<complex<f32>>) -> !fir.ref<tuple<f32, f32>>
- // I32: fir.call @paramcomplex4([[T]]) : (!fir.ref<tuple<f32, f32>>) -> ()
+ // I32: fir.call @paramcomplex4([[T]]) : (!fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}) -> ()
// I32_MINGW: [[ADDRI64:%[0-9A-Za-z]+]] = fir.alloca i64
// I32_MINGW: fir.store [[RES]] to [[ADDRI64]] : !fir.ref<i64>
@@ -244,7 +244,7 @@ func.func @callcomplex4(%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i3
// I32_MINGW: [[ADDRC2:%[0-9A-Za-z]+]] = fir.alloca complex<f32>
// I32_MINGW: fir.store [[C]] to [[ADDRC2]] : !fir.ref<complex<f32>>
// I32_MINGW: [[T:%[0-9A-Za-z]+]] = fir.convert [[ADDRC2]] : (!fir.ref<complex<f32>>) -> !fir.ref<tuple<f32, f32>>
- // I32_MINGW: fir.call @paramcomplex4([[T]]) : (!fir.ref<tuple<f32, f32>>) -> ()
+ // I32_MINGW: fir.call @paramcomplex4([[T]]) : (!fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}) -> ()
// X64: [[ADDRV:%[0-9A-Za-z]+]] = fir.alloca !fir.vector<2:f32>
// X64: fir.store [[RES]] to [[ADDRV]] : !fir.ref<!fir.vector<2:f32>>
@@ -442,12 +442,12 @@ func.func private @paramcomplex8(complex<f64>) -> ()
// LOONGARCH64-LABEL: func @callcomplex8()
func.func @callcomplex8() {
// I32: [[RES:%[0-9A-Za-z]+]] = fir.alloca tuple<f64, f64>
- // I32: fir.call @returncomplex8([[RES]]) : (!fir.ref<tuple<f64, f64>>) -> ()
+ // I32: fir.call @returncomplex8([[RES]]) : (!fir.ref<tuple<f64, f64>> {llvm.align = 4 : i32, llvm.sret = tuple<f64, f64>}) -> ()
// I32_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.alloca tuple<f64, f64>
- // I32_MINGW: fir.call @returncomplex8([[RES]]) : (!fir.ref<tuple<f64, f64>>) -> ()
+ // I32_MINGW: fir.call @returncomplex8([[RES]]) : (!fir.ref<tuple<f64, f64>> {llvm.align = 8 : i32, llvm.sret = tuple<f64, f64>}) -> ()
// X64: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple<f64, f64>
// X64_MINGW: [[RES:%[0-9A-Za-z]+]] = fir.alloca tuple<f64, f64>
- // X64_MINGW: fir.call @returncomplex8([[RES]]) : (!fir.ref<tuple<f64, f64>>) -> ()
+ // X64_MINGW: fir.call @returncomplex8([[RES]]) : (!fir.ref<tuple<f64, f64>> {llvm.align = 8 : i32, llvm.sret = tuple<f64, f64>}) -> ()
// AARCH64: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple<f64, f64>
// PPC64le: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple<f64, f64>
// SPARCV9: [[RES:%[0-9A-Za-z]+]] = fir.call @returncomplex8() : () -> tuple<f64, f64>
@@ -461,14 +461,14 @@ func.func @callcomplex8() {
// I32: [[ADDRC:%[0-9A-Za-z]+]] = fir.alloca complex<f64>
// I32: fir.store [[V]] to [[ADDRC]] : !fir.ref<complex<f64>>
// I32: [[ADDRT:%[0-9A-Za-z]+]] = fir.convert [[ADDRC]] : (!fir.ref<complex<f64>>) -> !fir.ref<tuple<f64, f64>>
- // I32: fir.call @paramcomplex8([[ADDRT]]) : (!fir.ref<tuple<f64, f64>>) -> ()
+ // I32: fir.call @paramcomplex8([[ADDRT]]) : (!fir.ref<tuple<f64, f64>> {llvm.align = 4 : i32, llvm.byval = tuple<f64, f64>}) -> ()
// I32_MINGW: [[RESC:%[0-9A-Za-z]+]] = fir.convert [[RES]] : (!fir.ref<tuple<f64, f64>>) -> !fir.ref<complex<f64>>
// I32_MINGW: [[V:%[0-9A-Za-z]+]] = fir.load [[RESC]] : !fir.ref<complex<f64>>
// I32_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.alloca complex<f64>
// I32_MINGW: fir.store [[V]] to [[ADDRC]] : !fir.ref<complex<f64>>
// I32_MINGW: [[ADDRT:%[0-9A-Za-z]+]] = fir.convert [[ADDRC]] : (!fir.ref<complex<f64>>) -> !fir.ref<tuple<f64, f64>>
- // I32_MINGW: fir.call @paramcomplex8([[ADDRT]]) : (!fir.ref<tuple<f64, f64>>) -> ()
+ // I32_MINGW: fir.call @paramcomplex8([[ADDRT]]) : (!fir.ref<tuple<f64, f64>> {llvm.align = 4 : i32, llvm.byval = tuple<f64, f64>}) -> ()
// X64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple<f64, f64>
// X64: fir.store [[RES]] to [[ADDRT]] : !fir.ref<tuple<f64, f64>>
@@ -483,7 +483,7 @@ func.func @callcomplex8() {
// X64_MINGW: [[ADDRC:%[0-9A-Za-z]+]] = fir.alloca complex<f64>
// X64_MINGW: fir.store [[V]] to [[ADDRC]] : !fir.ref<complex<f64>>
// X64_MINGW: [[ADDRT:%[0-9A-Za-z]+]] = fir.convert [[ADDRC]] : (!fir.ref<complex<f64>>) -> !fir.ref<tuple<f64, f64>>
- // X64_MINGW: fir.call @paramcomplex8([[ADDRT]]) : (!fir.ref<tuple<f64, f64>>) -> ()
+ // X64_MINGW: fir.call @paramcomplex8([[ADDRT]]) : (!fir.ref<tuple<f64, f64>> {llvm.align = 8 : i32, llvm.byval = tuple<f64, f64>}) -> ()
// AARCH64: [[ADDRT:%[0-9A-Za-z]+]] = fir.alloca tuple<f64, f64>
// AARCH64: fir.store [[RES]] to [[ADDRT]] : !fir.ref<tuple<f64, f64>>
@@ -590,7 +590,7 @@ func.func @multipleparamscomplex4(%z1 : complex<f32>, %z2 : complex<f32>, %z3 :
// I32-DAG: fir.store [[Z3_VAL]] to [[Z3_ADDRC]] : !fir.ref<complex<f32>>
// I32-DAG: [[Z3_ADDRT:%[0-9A-Za-z]+]] = fir.convert [[Z3_ADDRC]] : (!fir.ref<complex<f32>>) -> !fir.ref<tuple<f32, f32>>
- // I32: fir.call @calleemultipleparamscomplex4([[Z1_ADDRT]], [[Z2_ADDRT]], [[Z3_ADDRT]]) : (!fir.ref<tuple<f32, f32>>, !fir.ref<tuple<f32, f32>>, !fir.ref<tuple<f32, f32>>) -> ()
+ // I32: fir.call @calleemultipleparamscomplex4([[Z1_ADDRT]], [[Z2_ADDRT]], [[Z3_ADDRT]]) : (!fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}, !fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}, !fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}) -> ()
// I32_MINGW-DAG: [[Z1_ADDR:%[0-9A-Za-z]+]] = fir.convert [[Z1]] : (!fir.ref<tuple<f32, f32>>) -> !fir.ref<complex<f32>>
// I32_MINGW-DAG: [[Z1_VAL:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDR]] : !fir.ref<complex<f32>>
@@ -609,7 +609,7 @@ func.func @multipleparamscomplex4(%z1 : complex<f32>, %z2 : complex<f32>, %z3 :
// I32_MINGW-DAG: fir.store [[Z3_VAL]] to [[Z3_ADDRC]] : !fir.ref<complex<f32>>
// I32_MINGW-DAG: [[Z3_ADDRT:%[0-9A-Za-z]+]] = fir.convert [[Z3_ADDRC]] : (!fir.ref<complex<f32>>) -> !fir.ref<tuple<f32, f32>>
- // I32_MINGW: fir.call @calleemultipleparamscomplex4([[Z1_ADDRT]], [[Z2_ADDRT]], [[Z3_ADDRT]]) : (!fir.ref<tuple<f32, f32>>, !fir.ref<tuple<f32, f32>>, !fir.ref<tuple<f32, f32>>) -> ()
+ // I32_MINGW: fir.call @calleemultipleparamscomplex4([[Z1_ADDRT]], [[Z2_ADDRT]], [[Z3_ADDRT]]) : (!fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}, !fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}, !fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}) -> ()
// X64-DAG: [[Z3_ADDR:%[0-9A-Za-z]+]] = fir.alloca !fir.vector<2:f32>
// X64-DAG: fir.store [[Z3]] to [[Z3_ADDR]] : !fir.ref<!fir.vector<2:f32>>
@@ -838,7 +838,7 @@ func.func private @mlircomplexf32(%z1: complex<f32>, %z2: complex<f32>) -> compl
// I32-DAG: fir.store [[Z2_VAL]] to [[Z2_ADDRC]] : !fir.ref<complex<f32>>
// I32-DAG: [[Z2_ADDRT:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDRC]] : (!fir.ref<complex<f32>>) -> !fir.ref<tuple<f32, f32>>
- // I32: [[VAL:%[0-9A-Za-z]+]] = fir.call @mlircomplexf32([[Z1_ADDRT]], [[Z2_ADDRT]]) : (!fir.ref<tuple<f32, f32>>, !fir.ref<tuple<f32, f32>>) -> i64
+ // I32: [[VAL:%[0-9A-Za-z]+]] = fir.call @mlircomplexf32([[Z1_ADDRT]], [[Z2_ADDRT]]) : (!fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}, !fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}) -> i64
// I32_MINGW-DAG: [[Z1_ADDR:%[0-9A-Za-z]+]] = fir.convert [[Z1]] : (!fir.ref<tuple<f32, f32>>) -> !fir.ref<complex<f32>>
// I32_MINGW-DAG: [[Z1_VAL:%[0-9A-Za-z]+]] = fir.load [[Z1_ADDR]] : !fir.ref<complex<f32>>
@@ -852,7 +852,7 @@ func.func private @mlircomplexf32(%z1: complex<f32>, %z2: complex<f32>) -> compl
// I32_MINGW-DAG: fir.store [[Z2_VAL]] to [[Z2_ADDRC]] : !fir.ref<complex<f32>>
// I32_MINGW-DAG: [[Z2_ADDRT:%[0-9A-Za-z]+]] = fir.convert [[Z2_ADDRC]] : (!fir.ref<complex<f32>>) -> !fir.ref<tuple<f32, f32>>
- // I32_MINGW: [[VAL:%[0-9A-Za-z]+]] = fir.call @mlircomplexf32([[Z1_ADDRT]], [[Z2_ADDRT]]) : (!fir.ref<tuple<f32, f32>>, !fir.ref<tuple<f32, f32>>) -> i64
+ // I32_MINGW: [[VAL:%[0-9A-Za-z]+]] = fir.call @mlircomplexf32([[Z1_ADDRT]], [[Z2_ADDRT]]) : (!fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}, !fir.ref<tuple<f32, f32>> {llvm.align = 4 : i32, llvm.byval = tuple<f32, f32>}) -> i64
// X64-DAG: [[Z2_ADDR:%[0-9A-Za-z]+]] = fir.alloca !fir.vector<2:f32>
// X64-DAG: fir.store [[Z2]] to [[Z2_ADDR]] : !fir.ref<!fir.vector<2:f32>>
diff --git a/flang/test/Fir/target-rewrite-complex16.fir b/flang/test/Fir/target-rewrite-complex16.fir
index 86a5b0051ab2e..199aa73b879c5 100644
--- a/flang/test/Fir/target-rewrite-complex16.fir
+++ b/flang/test/Fir/target-rewrite-complex16.fir
@@ -66,7 +66,7 @@ func.func @addrof() {
// CHECK-LABEL: func.func @callcomplex16() {
// CHECK: %[[VAL_0:.*]] = llvm.intr.stacksave : !llvm.ptr
// CHECK: %[[VAL_1:.*]] = fir.alloca tuple<f128, f128>
-// CHECK: fir.call @returncomplex16(%[[VAL_1]]) : (!fir.ref<tuple<f128, f128>>) -> ()
+// CHECK: fir.call @returncomplex16(%[[VAL_1]]) : (!fir.ref<tuple<f128, f128>> {llvm.align = 16 : i32, llvm.sret = tuple<f128, f128>}) -> ()
// CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<tuple<f128, f128>>) -> !fir.ref<complex<f128>>
// CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref<complex<f128>>
// CHECK: llvm.intr.stackrestore %[[VAL_0]] : !llvm.ptr
@@ -74,7 +74,7 @@ func.func @addrof() {
// CHECK: %[[VAL_5:.*]] = fir.alloca complex<f128>
// CHECK: fir.store %[[VAL_3]] to %[[VAL_5]] : !fir.ref<complex<f128>>
// CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (!fir.ref<complex<f128>>) -> !fir.ref<tuple<f128, f128>>
-// CHECK: fir.call @paramcomplex16(%[[VAL_6]]) : (!fir.ref<tuple<f128, f128>>) -> ()
+// CHECK: fir.call @paramcomplex16(%[[VAL_6]]) : (!fir.ref<tuple<f128, f128>> {llvm.align = 16 : i32, llvm.byval = tuple<f128, f128>}) -> ()
// CHECK: llvm.intr.stackrestore %[[VAL_4]] : !llvm.ptr
// CHECK: return
// CHECK: }
@@ -98,7 +98,7 @@ func.func @addrof() {
// CHECK: %[[VAL_14:.*]] = fir.alloca complex<f128>
// CHECK: fir.store %[[VAL_4]] to %[[VAL_14]] : !fir.ref<complex<f128>>
// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (!fir.ref<complex<f128>>) -> !fir.ref<tuple<f128, f128>>
-// CHECK: fir.call @calleemultipleparamscomplex16(%[[VAL_11]], %[[VAL_13]], %[[VAL_15]]) : (!fir.ref<tuple<f128, f128>>, !fir.ref<tuple<f128, f128>>, !fir.ref<tuple<f128, f128>>) -> ()
+// CHECK: fir.call @calleemultipleparamscomplex16(%[[VAL_11]], %[[VAL_13]], %[[VAL_15]]) : (!fir.ref<tuple<f128, f128>> {llvm.align = 16 : i32, llvm.byval = tuple<f128, f128>}, !fir.ref<tuple<f128, f128>> {llvm.align = 16 : i32, llvm.byval = tuple<f128, f128>}, !fir.ref<tuple<f128, f128>> {llvm.align = 16 : i32, llvm.byval = tuple<f128, f128>}) -> ()
// CHECK: llvm.intr.stackrestore %[[VAL_9]] : !llvm.ptr
// CHECK: return
// CHECK: }
@@ -117,7 +117,7 @@ func.func @addrof() {
// CHECK: %[[VAL_11:.*]] = fir.alloca complex<f128>
// CHECK: fir.store %[[VAL_4]] to %[[VAL_11]] : !fir.ref<complex<f128>>
// CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.ref<complex<f128>>) -> !fir.ref<tuple<f128, f128>>
-// CHECK: fir.call @mlircomplexf128(%[[VAL_8]], %[[VAL_10]], %[[VAL_12]]) : (!fir.ref<tuple<f128, f128>>, !fir.ref<tuple<f128, f128>>, !fir.ref<tuple<f128, f128>>) -> ()
+// CHECK: fir.call @mlircomplexf128(%[[VAL_8]], %[[VAL_10]], %[[VAL_12]]) : (!fir.ref<tuple<f128, f128>> {llvm.align = 16 : i32, llvm.sret = tuple<f128, f128>}, !fir.ref<tuple<f128, f128>> {llvm.align = 16 : i32, llvm.byval = tuple<f128, f128>}, !fir.ref<tuple<f128, f128>> {llvm.align = 16 : i32, llvm.byval = tuple<f128, f128>}) -> ()
// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<tuple<f128, f128>>) -> !fir.ref<complex<f128>>
// CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref<complex<f128>>
// CHECK: llvm.intr.stackrestore %[[VAL_7]] : !llvm.ptr
diff --git a/flang/test/Fir/target-rewrite-indirect-calls.fir b/flang/test/Fir/target-rewrite-indirect-calls.fir
index dbb3d0823520c..58a9a260b9a98 100644
--- a/flang/test/Fir/target-rewrite-indirect-calls.fir
+++ b/flang/test/Fir/target-rewrite-indirect-calls.fir
@@ -16,7 +16,7 @@ func.func @test(%arg0: () -> (), %arg1: !fir.ref<!fir.type<t{a:!fir.array<5xf64>
// CHECK: %[[VAL_5:.*]] = llvm.intr.stacksave : !llvm.ptr
// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.type<t{a:!fir.array<5xf64>}>
// CHECK: fir.store %[[VAL_3]] to %[[VAL_6]] : !fir.ref<!fir.type<t{a:!fir.array<5xf64>}>>
-// CHECK: fir.call %[[VAL_4]](%[[VAL_6]], %[[VAL_2]]) : (!fir.ref<!fir.type<t{a:!fir.array<5xf64>}>> {llvm.byval = !fir.type<t{a:!fir.array<5xf64>}>}, f64) -> ()
+// CHECK: fir.call %[[VAL_4]](%[[VAL_6]], %[[VAL_2]]) : (!fir.ref<!fir.type<t{a:!fir.array<5xf64>}>> {llvm.align = 8 : i32, llvm.byval = !fir.type<t{a:!fir.array<5xf64>}>}, f64) -> ()
// CHECK: llvm.intr.stackrestore %[[VAL_5]] : !llvm.ptr
// CHECK: return
// CHECK: }
diff --git a/flang/test/Fir/target-rewrite-integer-loongarch64.fir b/flang/test/Fir/target-rewrite-integer-loongarch64.fir
index 8421cbbb41a9d..96d341caffb53 100644
--- a/flang/test/Fir/target-rewrite-integer-loongarch64.fir
+++ b/flang/test/Fir/target-rewrite-integer-loongarch64.fir
@@ -1,10 +1,11 @@
/// Test i32 passing and returning on LoongArch64
/// LoongArch64 LP64D ABI requires unsigned 32 bit integers to be sign extended.
-// REQUIRES: loongarch-registered-target
// RUN: fir-opt --target-rewrite="target=loongarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=LOONGARCH64
// RUN: tco -target="loongarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=LOONGARCH64_LLVM
+module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", llvm.target_triple = "loongarch64-unknown-linux-gnu"} {
+
// LOONGARCH64: func.func private @cfunc32(i32 {llvm.signext}) -> (i32 {llvm.signext}) attributes {fir.bindc_name = "cfunc32"}
// LOONGARCH64_LLVM: declare signext i32 @cfunc32(i32 signext)
@@ -25,3 +26,4 @@ func.func @foo(%0: i32) -> i32 attributes {fir.bindc_name = "foo"} {
%1 = fir.call @cfunc32(%0) fastmath<contract> : (i32) -> i32
return %1 : i32
}
+}
diff --git a/flang/test/Fir/target.fir b/flang/test/Fir/target.fir
index 62ce488a3ca2f..781d153f525ff 100644
--- a/flang/test/Fir/target.fir
+++ b/flang/test/Fir/target.fir
@@ -68,7 +68,7 @@ func.func @call4() {
// AARCH64: = call { float, float } @gen4()
// PPC: = call { float, float } @gen4()
%1 = fir.call @gen4() : () -> complex<f32>
- // I32: call void @sink4(ptr %
+ // I32: call void @sink4(ptr byval({ float, float }) align 4 %
// X64: call void @sink4(<2 x float> %
// AARCH64: call void @sink4([2 x float] %
// PPC: call void @sink4(float %{{.*}}, float %{{.*}})
@@ -80,12 +80,12 @@ func.func @call4() {
// X64-LABEL: define void @call8()
// AARCH64-LABEL: define void @call8()
func.func @call8() {
- // I32: call void @gen8(ptr %
+ // I32: call void @gen8(ptr sret({ double, double }) align 4 %
// X64: = call { double, double } @gen8()
// AARCH64: = call { double, double } @gen8()
// PPC: = call { double, double } @gen8()
%1 = fir.call @gen8() : () -> complex<f64>
- // I32: call void @sink8(ptr %
+ // I32: call void @sink8(ptr byval({ double, double }) align 4 %
// X64: call void @sink8(double %{{[0-9]*}}, double %{{[0-9]*}})
// AARCH64: call void @sink8([2 x double] %
// PPC: call void @sink8(double %{{.*}}, double %{{.*}})
More information about the flang-commits
mailing list