Skip to content

Commit 15e335f

Browse files
authored
[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 38565da 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).
1 parent c9563a4 commit 15e335f

17 files changed

+74
-72
lines changed

flang/lib/Optimizer/CodeGen/TargetRewrite.cpp

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -541,37 +541,37 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
541541
callOp.getContext(),
542542
mlir::TypeRange{newInTypes}.drop_front(dropFront), newResTys));
543543
newCall = rewriter->create<fir::CallOp>(loc, newResTys, newOpers);
544-
// Set ABI argument attributes on call operation since they are not
545-
// accessible via a FuncOp in indirect calls.
546-
if (hasByValOrSRetArgs(newInTyAndAttrs)) {
547-
llvm::SmallVector<mlir::Attribute> argAttrsArray;
548-
for (const auto &arg :
549-
llvm::ArrayRef<fir::CodeGenSpecifics::TypeAndAttr>(
550-
newInTyAndAttrs)
551-
.drop_front(dropFront)) {
552-
mlir::NamedAttrList argAttrs;
553-
const auto &attr = std::get<fir::CodeGenSpecifics::Attributes>(arg);
554-
if (attr.isByVal()) {
555-
mlir::Type elemType =
556-
fir::dyn_cast_ptrOrBoxEleTy(std::get<mlir::Type>(arg));
557-
argAttrs.set(mlir::LLVM::LLVMDialect::getByValAttrName(),
558-
mlir::TypeAttr::get(elemType));
559-
} else if (attr.isSRet()) {
560-
mlir::Type elemType =
561-
fir::dyn_cast_ptrOrBoxEleTy(std::get<mlir::Type>(arg));
562-
argAttrs.set(mlir::LLVM::LLVMDialect::getStructRetAttrName(),
563-
mlir::TypeAttr::get(elemType));
564-
if (auto align = attr.getAlignment()) {
565-
argAttrs.set(mlir::LLVM::LLVMDialect::getAlignAttrName(),
566-
rewriter->getIntegerAttr(
567-
rewriter->getIntegerType(32), align));
568-
}
569-
}
570-
argAttrsArray.emplace_back(
571-
argAttrs.getDictionary(rewriter->getContext()));
544+
}
545+
// Always set ABI argument attributes on call operations, even when
546+
// direct, as required by
547+
// https://llvm.org/docs/LangRef.html#parameter-attributes.
548+
if (hasByValOrSRetArgs(newInTyAndAttrs)) {
549+
llvm::SmallVector<mlir::Attribute> argAttrsArray;
550+
for (const auto &arg :
551+
llvm::ArrayRef<fir::CodeGenSpecifics::TypeAndAttr>(newInTyAndAttrs)
552+
.drop_front(dropFront)) {
553+
mlir::NamedAttrList argAttrs;
554+
const auto &attr = std::get<fir::CodeGenSpecifics::Attributes>(arg);
555+
if (attr.isByVal()) {
556+
mlir::Type elemType =
557+
fir::dyn_cast_ptrOrBoxEleTy(std::get<mlir::Type>(arg));
558+
argAttrs.set(mlir::LLVM::LLVMDialect::getByValAttrName(),
559+
mlir::TypeAttr::get(elemType));
560+
} else if (attr.isSRet()) {
561+
mlir::Type elemType =
562+
fir::dyn_cast_ptrOrBoxEleTy(std::get<mlir::Type>(arg));
563+
argAttrs.set(mlir::LLVM::LLVMDialect::getStructRetAttrName(),
564+
mlir::TypeAttr::get(elemType));
565+
}
566+
if (auto align = attr.getAlignment()) {
567+
argAttrs.set(
568+
mlir::LLVM::LLVMDialect::getAlignAttrName(),
569+
rewriter->getIntegerAttr(rewriter->getIntegerType(32), align));
572570
}
573-
newCall.setArgAttrsAttr(rewriter->getArrayAttr(argAttrsArray));
571+
argAttrsArray.emplace_back(
572+
argAttrs.getDictionary(rewriter->getContext()));
574573
}
574+
newCall.setArgAttrsAttr(rewriter->getArrayAttr(argAttrsArray));
575575
}
576576
LLVM_DEBUG(llvm::dbgs() << "replacing call with " << newCall << '\n');
577577
if (wrap)

flang/test/Fir/CUDA/cuda-target-rewrite.mlir

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
// REQUIRES: x86-registered-target
21
// RUN: fir-opt --split-input-file --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s
32

3+
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"} {
4+
45
gpu.module @testmod {
56
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>} {
67
%0 = fir.alloca i64
@@ -15,22 +16,25 @@ gpu.module @testmod {
1516
// CHECK-LABEL: gpu.func @_QPvcpowdk
1617
// CHECK: %{{.*}} = fir.call @_FortranAzpowk(%{{.*}}, %{{.*}}, %{{.*}}) : (f64, f64, i64) -> tuple<f64, f64>
1718
// CHECK: func.func private @_FortranAzpowk(f64, f64, i64) -> tuple<f64, f64> attributes {fir.bindc_name = "_FortranAzpowk", fir.runtime}
19+
}
1820

1921
// -----
2022

23+
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"} {
24+
2125
gpu.module @testmod {
2226
gpu.func @_QPtest(%arg0: complex<f64>) -> (complex<f64>) {
2327
gpu.return %arg0 : complex<f64>
2428
}
2529
}
30+
}
2631

2732
// CHECK-LABEL: gpu.func @_QPtest
2833
// CHECK-SAME: (%arg0: f64, %arg1: f64) -> tuple<f64, f64> {
2934
// CHECK: gpu.return %{{.*}} : tuple<f64, f64>
3035

31-
3236
// -----
33-
module attributes {gpu.container_module} {
37+
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"} {
3438

3539
gpu.module @testmod {
3640
gpu.func @_QPtest(%arg0: complex<f64>) -> () kernel {

flang/test/Fir/struct-passing-return-loongarch64-bystack.fir

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/// Test LoongArch64 ABI rewrite of struct passed and returned by value (BIND(C), VALUE derived types).
22
/// This test test cases where the struct must be passed or returned on the stack.
33

4-
// REQUIRES: loongarch-registered-target
54
// RUN: tco --target=loongarch64-unknown-linux-gnu %s | FileCheck %s
65

76
!ty_int_toobig = !fir.type<int_toobig{i:!fir.array<5xi32>}>

flang/test/Fir/struct-passing-x86-64-byval.fir

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Test X86-64 ABI rewrite of struct passed by value (BIND(C), VALUE derived types).
22
// This test test cases where the struct must be passed on the stack according
33
// to the System V ABI.
4-
// REQUIRES: x86-registered-target
54
// RUN: tco --target=x86_64-unknown-linux-gnu %s | FileCheck %s
65

76
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"} {

flang/test/Fir/struct-passing-x86-64-one-field-inreg.fir

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Test X86-64 passing ABI of struct in registers for the simple case
22
// where the struct has a single intrinsic component that is not a complex.
3-
// REQUIRES: x86-registered-target
43
// RUN: fir-opt -target-rewrite="target=x86_64-unknown-linux-gnu" %s -o - | FileCheck %s
54

65
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"} {

flang/test/Fir/struct-passing-x86-64-several-fields-inreg.fir

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Test X86-64 passing ABI of struct in registers for the cases where the
22
// struct has more than one field.
3-
// REQUIRES: x86-registered-target
43
// RUN: fir-opt -target-rewrite="target=x86_64-unknown-linux-gnu" %s -o - | FileCheck %s
54

65

flang/test/Fir/struct-return-aarch64.fir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func.func private @test_too_big() -> !too_big
125125
func.func @test_call_too_big(%arg0 : !fir.ref<!too_big>) {
126126
// CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
127127
// CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t7{x:i64,y:i64,z:i64}>
128-
// CHECK: fir.call @test_too_big(%[[ARG]]) : (!fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>) -> ()
128+
// 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}>}) -> ()
129129
// 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}>>
130130
// CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t7{x:i64,y:i64,z:i64}>>
131131
// CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr
@@ -145,7 +145,7 @@ func.func private @test_too_big_hfa() -> !too_big_hfa
145145
func.func @test_call_too_big_hfa(%arg0 : !fir.ref<!too_big_hfa>) {
146146
// CHECK: %[[STACK:.*]] = llvm.intr.stacksave : !llvm.ptr
147147
// CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t8{i:!fir.array<5xf32>}>
148-
// CHECK: fir.call @test_too_big_hfa(%[[ARG]]) : (!fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>) -> ()
148+
// 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>}>}) -> ()
149149
// CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>) -> !fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>
150150
// CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t8{i:!fir.array<5xf32>}>>
151151
// CHECK: llvm.intr.stackrestore %[[STACK]] : !llvm.ptr

flang/test/Fir/struct-return-loongarch64-byreg.fir

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
/// only the first example in each category checks the entire invocation process,
88
/// while the other examples only check the signatures.
99

10-
// REQUIRES: loongarch-registered-target
1110
// RUN: fir-opt --split-input-file --target-rewrite="target=loongarch64-unknown-linux-gnu" %s | FileCheck %s
1211

1312

flang/test/Fir/struct-return-powerpc64-aix.fir

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func.func @test_call_t1(%arg0 : !fir.ref<!fir.type<t1<{c:!fir.char<1>}>>>) {
1515
return
1616
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
1717
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t1<{c:!fir.char<1>}>>
18-
//CHECK: fir.call @test_t1(%[[ARG]]) : (!fir.ref<!fir.type<t1<{c:!fir.char<1>}>>>) -> ()
18+
//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>}>>}) -> ()
1919
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t1<{c:!fir.char<1>}>>>) -> !fir.ref<!fir.type<t1<{c:!fir.char<1>}>>>
2020
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t1<{c:!fir.char<1>}>>>
2121
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr
@@ -34,7 +34,7 @@ func.func @test_call_t2(%arg0 : !fir.ref<!fir.type<t2<{i:i32}>>>) {
3434
return
3535
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
3636
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t2<{i:i32}>>
37-
//CHECK: fir.call @test_t2(%[[ARG]]) : (!fir.ref<!fir.type<t2<{i:i32}>>>) -> ()
37+
//CHECK: fir.call @test_t2(%[[ARG]]) : (!fir.ref<!fir.type<t2<{i:i32}>>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t2<{i:i32}>>}) -> ()
3838
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t2<{i:i32}>>>) -> !fir.ref<!fir.type<t2<{i:i32}>>>
3939
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t2<{i:i32}>>>
4040
//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}>>>)
5353
return
5454
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
5555
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t3<{r1:f32,r2:f32,r3:f32}>>
56-
//CHECK: fir.call @test_t3(%[[ARG]]) : (!fir.ref<!fir.type<t3<{r1:f32,r2:f32,r3:f32}>>>) -> ()
56+
//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}>>}) -> ()
5757
//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}>>>
5858
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t3<{r1:f32,r2:f32,r3:f32}>>>
5959
//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>}>>>)
7272
return
7373
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
7474
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t4<{r:!fir.array<8xf32>}>>
75-
//CHECK: fir.call @test_t4(%[[ARG]]) : (!fir.ref<!fir.type<t4<{r:!fir.array<8xf32>}>>>) -> ()
75+
//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>}>>}) -> ()
7676
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t4<{r:!fir.array<8xf32>}>>>) -> !fir.ref<!fir.type<t4<{r:!fir.array<8xf32>}>>>
7777
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t4<{r:!fir.array<8xf32>}>>>
7878
//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
9191
return
9292
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
9393
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t5<{c:!fir.char<1>,r:f32,i:i64}>>
94-
//CHECK: fir.call @test_t5(%[[ARG]]) : (!fir.ref<!fir.type<t5<{c:!fir.char<1>,r:f32,i:i64}>>>) -> ()
94+
//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}>>}) -> ()
9595
//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}>>>
9696
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t5<{c:!fir.char<1>,r:f32,i:i64}>>>
9797
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr

flang/test/Fir/struct-return-ppc64le.fir

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func.func @test_call_t1(%arg0 : !fir.ref<!fir.type<t1{c:!fir.char<1>}>>) {
1515
return
1616
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
1717
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t1{c:!fir.char<1>}>
18-
//CHECK: fir.call @test_t1(%[[ARG]]) : (!fir.ref<!fir.type<t1{c:!fir.char<1>}>>) -> ()
18+
//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>}>}) -> ()
1919
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t1{c:!fir.char<1>}>>) -> !fir.ref<!fir.type<t1{c:!fir.char<1>}>>
2020
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t1{c:!fir.char<1>}>>
2121
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr
@@ -34,7 +34,7 @@ func.func @test_call_t2(%arg0 : !fir.ref<!fir.type<t2{i:i32}>>) {
3434
return
3535
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
3636
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t2{i:i32}>
37-
//CHECK: fir.call @test_t2(%[[ARG]]) : (!fir.ref<!fir.type<t2{i:i32}>>) -> ()
37+
//CHECK: fir.call @test_t2(%[[ARG]]) : (!fir.ref<!fir.type<t2{i:i32}>> {llvm.align = 8 : i32, llvm.sret = !fir.type<t2{i:i32}>}) -> ()
3838
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t2{i:i32}>>) -> !fir.ref<!fir.type<t2{i:i32}>>
3939
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t2{i:i32}>>
4040
//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>}>>) {
7373
return
7474
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
7575
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t4{r:!fir.array<9xf32>}>
76-
//CHECK: fir.call @test_t4(%[[ARG]]) : (!fir.ref<!fir.type<t4{r:!fir.array<9xf32>}>>) -> ()
76+
//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>}>}) -> ()
7777
//CHECK: %[[CVT:.*]] = fir.convert %[[ARG]] : (!fir.ref<!fir.type<t4{r:!fir.array<9xf32>}>>) -> !fir.ref<!fir.type<t4{r:!fir.array<9xf32>}>>
7878
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t4{r:!fir.array<9xf32>}>>
7979
//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
9292
return
9393
//CHECK: %[[STCK:.*]] = llvm.intr.stacksave : !llvm.ptr
9494
//CHECK: %[[ARG:.*]] = fir.alloca !fir.type<t5{c:!fir.char<1>,r:f32,i:i64}>
95-
//CHECK: fir.call @test_t5(%[[ARG]]) : (!fir.ref<!fir.type<t5{c:!fir.char<1>,r:f32,i:i64}>>) -> ()
95+
//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}>}) -> ()
9696
//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}>>
9797
//CHECK: %[[LD:.*]] = fir.load %[[CVT]] : !fir.ref<!fir.type<t5{c:!fir.char<1>,r:f32,i:i64}>>
9898
//CHECK: llvm.intr.stackrestore %[[STCK]] : !llvm.ptr

flang/test/Fir/struct-return-x86-64.fir

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// Test X86-64 ABI rewrite of struct returned by value (BIND(C), VALUE derived types).
2-
// REQUIRES: x86-registered-target
32
// RUN: fir-opt --target-rewrite %s | FileCheck %s
43

54
!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
8685
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>) {
8786
// CHECK: %[[VAL_1:.*]] = llvm.intr.stacksave : !llvm.ptr
8887
// CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<t2{i:!fir.array<5xf32>}>
89-
// CHECK: fir.call @test_sret(%[[VAL_2]]) : (!fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>) -> ()
88+
// 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>}>}) -> ()
9089
// 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>}>>
9190
// CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.type<t2{i:!fir.array<5xf32>}>>
9291
// CHECK: llvm.intr.stackrestore %[[VAL_1]] : !llvm.ptr

flang/test/Fir/target-rewrite-complex-10-x86.fir

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
// Test COMPLEX(10) passing and returning on X86
2-
// REQUIRES: x86-registered-target
32
// RUN: fir-opt --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=AMD64
43
// RUN: tco -target="x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=AMD64_LLVM
54

5+
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"} {
6+
67
func.func @returncomplex10() -> complex<f80> {
78
%1 = fir.zero_bits complex<f80>
89
return %1 : complex<f80>
@@ -30,3 +31,4 @@ func.func @takecomplex10(%z: complex<f80>) {
3031
// AMD64: fir.store %[[VAL_2]] to %[[VAL_3]] : !fir.ref<complex<f80>>
3132

3233
// AMD64_LLVM: define void @takecomplex10(ptr byval({ x86_fp80, x86_fp80 }) align 16 captures(none) %0)
34+
}

0 commit comments

Comments
 (0)