- Notifications
You must be signed in to change notification settings - Fork 15.3k
[flang] also set llvm ABI argument attributes on direct calls #130736
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| @llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-flang-codegen Author: None (jeanPerier) ChangesSo 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 Patch is 36.76 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/130736.diff 17 Files Affected:
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... [truncated] |
tblah left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch. LGTM and tests pass fine on aarch64
vzakhari left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, Jean!
kkwli left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
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)atO2and above on X86-64 for complex(16).