diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp index 374308fa5894..7dbf21ce0c12 100644 --- a/flang/lib/Optimizer/CodeGen/Target.cpp +++ b/flang/lib/Optimizer/CodeGen/Target.cpp @@ -784,7 +784,7 @@ struct TargetX86_64Win : public GenericTarget { } // namespace //===----------------------------------------------------------------------===// -// AArch64 linux target specifics. +// AArch64 target specifics. //===----------------------------------------------------------------------===// namespace { @@ -810,6 +810,34 @@ struct TargetAArch64 : public GenericTarget { return marshal; } + CodeGenSpecifics::Marshalling + integerArgumentType(mlir::Location loc, + mlir::IntegerType argTy) const override { + if (argTy.getWidth() < getCIntTypeWidth() && argTy.isSignless()) { + AT::IntegerExtension intExt; + if (argTy.getWidth() == 1) { + // Zero extend for 'i1'. + intExt = AT::IntegerExtension::Zero; + } else { + if (triple.isOSDarwin()) { + // On Darwin, sign extend. The apple developer guide specifies this as + // a divergence from the AArch64PCS: + // https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Pass-arguments-to-functions-correctly + intExt = AT::IntegerExtension::Sign; + } else { + // On linux, pass directly and do not extend. + intExt = AT::IntegerExtension::None; + } + } + CodeGenSpecifics::Marshalling marshal; + marshal.emplace_back(argTy, AT{/*alignment=*/0, /*byval=*/false, + /*sret=*/false, /*append=*/false, + /*intExt=*/intExt}); + return marshal; + } + return GenericTarget::integerArgumentType(loc, argTy); + } + CodeGenSpecifics::Marshalling complexReturnType(mlir::Location loc, mlir::Type eleTy) const override { CodeGenSpecifics::Marshalling marshal; diff --git a/flang/test/Fir/convert-to-llvm-target.fir b/flang/test/Fir/convert-to-llvm-target.fir index bb873080072f..6adc5cd4b737 100644 --- a/flang/test/Fir/convert-to-llvm-target.fir +++ b/flang/test/Fir/convert-to-llvm-target.fir @@ -1,7 +1,7 @@ // RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefix INT64 // RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefixes INT64 // RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=i386-unknown-linux-gnu" %s | FileCheck %s --check-prefixes INT32 -// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=powerpc64le-unknown-linux-gn" %s | FileCheck %s --check-prefixes INT64 +// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=powerpc64le-unknown-linux-gnu" %s | FileCheck %s --check-prefixes INT64 //============================================================================= // SUMMARY: Tests for FIR --> LLVM MLIR conversion that *depend* on the target diff --git a/flang/test/Fir/target-rewrite-integer.fir b/flang/test/Fir/target-rewrite-integer.fir index 3be76e21a420..4cb2026cf9ee 100644 --- a/flang/test/Fir/target-rewrite-integer.fir +++ b/flang/test/Fir/target-rewrite-integer.fir @@ -1,6 +1,8 @@ // RUN: fir-opt --split-input-file --target-rewrite="target=i386-unknown-linux-gnu" %s | FileCheck %s --check-prefixes=I32,ALL // RUN: fir-opt --split-input-file --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefixes=X64,ALL +// RUN: fir-opt --split-input-file --target-rewrite="target=x86_64-apple-darwin" %s | FileCheck %s --check-prefixes=X64,ALL // RUN: fir-opt --split-input-file --target-rewrite="target=aarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefixes=AARCH64,ALL +// RUN: fir-opt --split-input-file --target-rewrite="target=aarch64-apple-darwin" %s | FileCheck %s --check-prefixes=AARCH64DARWIN,ALL // RUN: fir-opt --split-input-file --target-rewrite="target=powerpc64le-unknown-linux-gnu" %s | FileCheck %s --check-prefixes=PPC,ALL // RUN: fir-opt --split-input-file --target-rewrite="target=sparc64-unknown-linux-gnu" %s | FileCheck %s --check-prefixes=SPARCV9,ALL // RUN: fir-opt --split-input-file --target-rewrite="target=sparcv9-sun-solaris2.11" %s | FileCheck %s --check-prefixes=SPARCV9,ALL @@ -17,6 +19,7 @@ // I32: func.func{{.*}}@_FortranAioOutputLogical({{.*}}i1 {llvm.zeroext}) -> (i1 {llvm.zeroext}) // X64: func.func{{.*}}@_FortranAioOutputLogical({{.*}}i1 {llvm.zeroext}) -> (i1 {llvm.zeroext}) // AARCH64: func.func{{.*}}@_FortranAioOutputLogical({{.*}}i1 {llvm.zeroext}) -> (i1 {llvm.zeroext}) +// AARCH64DARWIN: func.func{{.*}}@_FortranAioOutputLogical({{.*}}i1 {llvm.zeroext}) -> (i1 {llvm.zeroext}) // PPC: func.func{{.*}}@_FortranAioOutputLogical({{.*}}i1 {llvm.zeroext}) -> (i1 {llvm.zeroext}) // SPARCV9: func.func{{.*}}@_FortranAioOutputLogical({{.*}}i1 {llvm.zeroext}) -> (i1 {llvm.zeroext}) // LOONGARCH64: func.func{{.*}}@_FortranAioOutputLogical({{.*}}i1 {llvm.zeroext}) -> (i1 {llvm.zeroext}) @@ -49,6 +52,7 @@ func.func private @_FortranAioEndIoStatement(!fir.ref) -> i32 attributes {fi // I32: func.func{{.*}}@_SomeFunc_si1(si1 {llvm.signext}) -> (si1 {llvm.signext}) // X64: func.func{{.*}}@_SomeFunc_si1(si1 {llvm.signext}) -> (si1 {llvm.signext}) // AARCH64: func.func{{.*}}@_SomeFunc_si1(si1 {llvm.signext}) -> (si1 {llvm.signext}) +// AARCH64DARWIN: func.func{{.*}}@_SomeFunc_si1(si1 {llvm.signext}) -> (si1 {llvm.signext}) // PPC: func.func{{.*}}@_SomeFunc_si1(si1 {llvm.signext}) -> (si1 {llvm.signext}) // SPARCV9: func.func{{.*}}@_SomeFunc_si1(si1 {llvm.signext}) -> (si1 {llvm.signext}) // LOONGARCH64: func.func{{.*}}@_SomeFunc_si1(si1 {llvm.signext}) -> (si1 {llvm.signext}) @@ -69,6 +73,7 @@ func.func private @_SomeFunc_si1(si1) -> si1 attributes {fir.runtime} // I32: func.func{{.*}}@_SomeFunc_ui1(ui1 {llvm.zeroext}) -> (ui1 {llvm.zeroext}) // X64: func.func{{.*}}@_SomeFunc_ui1(ui1 {llvm.zeroext}) -> (ui1 {llvm.zeroext}) // AARCH64: func.func{{.*}}@_SomeFunc_ui1(ui1 {llvm.zeroext}) -> (ui1 {llvm.zeroext}) +// AARCH64DARWIN: func.func{{.*}}@_SomeFunc_ui1(ui1 {llvm.zeroext}) -> (ui1 {llvm.zeroext}) // PPC: func.func{{.*}}@_SomeFunc_ui1(ui1 {llvm.zeroext}) -> (ui1 {llvm.zeroext}) // SPARCV9: func.func{{.*}}@_SomeFunc_ui1(ui1 {llvm.zeroext}) -> (ui1 {llvm.zeroext}) // LOONGARCH64: func.func{{.*}}@_SomeFunc_ui1(ui1 {llvm.zeroext}) -> (ui1 {llvm.zeroext}) @@ -99,8 +104,20 @@ func.func private @_SomeFunc_ui1(ui1) -> ui1 attributes {fir.runtime} // end subroutine test // ALL-LABEL: @_QPtest_bindc -// ALL: func.func private @cfun8(i8 {llvm.signext}) -> (i8 {llvm.signext}) attributes {fir.bindc_name = "cfun8"} -// ALL: func.func private @cfun16(i16 {llvm.signext}) -> (i16 {llvm.signext}) attributes {fir.bindc_name = "cfun16"} +// I32: func.func private @cfun8(i8 {llvm.signext}) -> (i8 {llvm.signext}) attributes {fir.bindc_name = "cfun8"} +// I32: func.func private @cfun16(i16 {llvm.signext}) -> (i16 {llvm.signext}) attributes {fir.bindc_name = "cfun16"} +// X64: func.func private @cfun8(i8 {llvm.signext}) -> (i8 {llvm.signext}) attributes {fir.bindc_name = "cfun8"} +// X64: func.func private @cfun16(i16 {llvm.signext}) -> (i16 {llvm.signext}) attributes {fir.bindc_name = "cfun16"} +// AARCH64: func.func private @cfun8(i8) -> i8 attributes {fir.bindc_name = "cfun8"} +// AARCH64: func.func private @cfun16(i16) -> i16 attributes {fir.bindc_name = "cfun16"} +// AARCH64DARWIN: func.func private @cfun8(i8 {llvm.signext}) -> (i8 {llvm.signext}) attributes {fir.bindc_name = "cfun8"} +// AARCH64DARWIN: func.func private @cfun16(i16 {llvm.signext}) -> (i16 {llvm.signext}) attributes {fir.bindc_name = "cfun16"} +// PPC: func.func private @cfun8(i8 {llvm.signext}) -> (i8 {llvm.signext}) attributes {fir.bindc_name = "cfun8"} +// PPC: func.func private @cfun16(i16 {llvm.signext}) -> (i16 {llvm.signext}) attributes {fir.bindc_name = "cfun16"} +// SPARCV9: func.func private @cfun8(i8 {llvm.signext}) -> (i8 {llvm.signext}) attributes {fir.bindc_name = "cfun8"} +// SPARCV9: func.func private @cfun16(i16 {llvm.signext}) -> (i16 {llvm.signext}) attributes {fir.bindc_name = "cfun16"} +// LOONGARCH64: func.func private @cfun8(i8 {llvm.signext}) -> (i8 {llvm.signext}) attributes {fir.bindc_name = "cfun8"} +// LOONGARCH64: func.func private @cfun16(i16 {llvm.signext}) -> (i16 {llvm.signext}) attributes {fir.bindc_name = "cfun16"} func.func @_QPtest_bindc(%arg0: !fir.ref {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "y"}) { %0 = fir.load %arg0 : !fir.ref %1 = fir.call @cfun8(%0) fastmath : (i8) -> i8