[PATCH] D78756: [SveEmitter] Add builtins for svreinterpret
This revision was automatically updated to reflect the committed changes. Closed by commit rG5ba329059f9c: [SveEmitter] Add builtins for svreinterpret (authored by sdesmalen). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78756/new/ https://reviews.llvm.org/D78756 Files: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c clang/utils/TableGen/SveEmitter.cpp Index: clang/utils/TableGen/SveEmitter.cpp === --- clang/utils/TableGen/SveEmitter.cpp +++ clang/utils/TableGen/SveEmitter.cpp @@ -237,6 +237,23 @@ class SVEEmitter { private: + // The reinterpret builtins are generated separately because they + // need the cross product of all types (121 functions in total), + // which is inconvenient to specify in the arm_sve.td file or + // generate in CGBuiltin.cpp. + struct ReinterpretTypeInfo { +const char *Suffix; +const char *Type; +const char *BuiltinType; + }; + SmallVector Reinterprets = { + {"s8", "svint8_t", "q16Sc"}, {"s16", "svint16_t", "q8Ss"}, + {"s32", "svint32_t", "q4Si"}, {"s64", "svint64_t", "q2SWi"}, + {"u8", "svuint8_t", "q16Uc"}, {"u16", "svuint16_t", "q8Us"}, + {"u32", "svuint32_t", "q4Ui"}, {"u64", "svuint64_t", "q2UWi"}, + {"f16", "svfloat16_t", "q8h"}, {"f32", "svfloat32_t", "q4f"}, + {"f64", "svfloat64_t", "q2d"}}; + RecordKeeper llvm::StringMap EltTypes; llvm::StringMap MemEltTypes; @@ -1008,6 +1025,10 @@ OS << "#error \"SVE support not enabled\"\n"; OS << "#else\n\n"; + OS << "#if !defined(__LITTLE_ENDIAN__)\n"; + OS << "#error \"Big endian is currently not supported for arm_sve.h\"\n"; + OS << "#endif\n"; + OS << "#include \n\n"; OS << "#ifdef __cplusplus\n"; OS << "extern \"C\" {\n"; @@ -1074,6 +1095,22 @@ OS << "#define __aio static inline __attribute__((__always_inline__, " "__nodebug__, __overloadable__))\n\n"; + // Add reinterpret functions. + for (auto ShortForm : { false, true } ) +for (const ReinterpretTypeInfo : Reinterprets) + for (const ReinterpretTypeInfo : Reinterprets) { +if (ShortForm) { + OS << "__aio " << From.Type << " svreinterpret_" << From.Suffix; + OS << "(" << To.Type << " op) {\n"; + OS << " return __builtin_sve_reinterpret_" << From.Suffix << "_" + << To.Suffix << "(op);\n"; + OS << "}\n\n"; +} else + OS << "#define svreinterpret_" << From.Suffix << "_" << To.Suffix + << "(...) __builtin_sve_reinterpret_" << From.Suffix << "_" + << To.Suffix << "(__VA_ARGS__)\n"; + } + SmallVector, 128> Defs; std::vector RV = Records.getAllDerivedDefinitions("Inst"); for (auto *R : RV) @@ -1148,8 +1185,16 @@ OS << "BUILTIN(__builtin_sve_" << Def->getMangledName() << ", \"" << Def->getBuiltinTypeStr() << "\", \"n\")\n"; } + + // Add reinterpret builtins + for (const ReinterpretTypeInfo : Reinterprets) +for (const ReinterpretTypeInfo : Reinterprets) + OS << "BUILTIN(__builtin_sve_reinterpret_" << From.Suffix << "_" + << To.Suffix << +", \"" << From.BuiltinType << To.BuiltinType + << "\", \"n\")\n"; + OS << "#endif\n\n"; -} + } void SVEEmitter::createCodeGenMap(raw_ostream ) { std::vector RV = Records.getAllDerivedDefinitions("Inst"); Index: clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c === --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64_be-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s + +// expected-error@* {{Big endian is currently not supported for arm_sve.h}} +#include Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c === --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c @@ -0,0 +1,960 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svint8_t test_svreinterpret_s8_s8(svint8_t op) +{ + // CHECK-LABEL: test_svreinterpret_s8_s8 + // CHECK: ret
[PATCH] D78756: [SveEmitter] Add builtins for svreinterpret
efriedma accepted this revision. efriedma added a comment. This revision is now accepted and ready to land. LGTM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78756/new/ https://reviews.llvm.org/D78756 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D78756: [SveEmitter] Add builtins for svreinterpret
sdesmalen updated this revision to Diff 261892. sdesmalen added a comment. - Added FIXME in CGBuiltins for big-endian svreinterpret. - Added diagnostic in arm_sve.h that big-endian is not yet supported. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78756/new/ https://reviews.llvm.org/D78756 Files: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c clang/utils/TableGen/SveEmitter.cpp Index: clang/utils/TableGen/SveEmitter.cpp === --- clang/utils/TableGen/SveEmitter.cpp +++ clang/utils/TableGen/SveEmitter.cpp @@ -237,6 +237,23 @@ class SVEEmitter { private: + // The reinterpret builtins are generated separately because they + // need the cross product of all types (121 functions in total), + // which is inconvenient to specify in the arm_sve.td file or + // generate in CGBuiltin.cpp. + struct ReinterpretTypeInfo { +const char *Suffix; +const char *Type; +const char *BuiltinType; + }; + SmallVector Reinterprets = { + {"s8", "svint8_t", "q16Sc"}, {"s16", "svint16_t", "q8Ss"}, + {"s32", "svint32_t", "q4Si"}, {"s64", "svint64_t", "q2SWi"}, + {"u8", "svuint8_t", "q16Uc"}, {"u16", "svuint16_t", "q8Us"}, + {"u32", "svuint32_t", "q4Ui"}, {"u64", "svuint64_t", "q2UWi"}, + {"f16", "svfloat16_t", "q8h"}, {"f32", "svfloat32_t", "q4f"}, + {"f64", "svfloat64_t", "q2d"}}; + RecordKeeper llvm::StringMap EltTypes; llvm::StringMap MemEltTypes; @@ -1008,6 +1025,10 @@ OS << "#error \"SVE support not enabled\"\n"; OS << "#else\n\n"; + OS << "#if !defined(__LITTLE_ENDIAN__)\n"; + OS << "#error \"Big endian is currently not supported for arm_sve.h\"\n"; + OS << "#endif\n"; + OS << "#include \n\n"; OS << "#ifdef __cplusplus\n"; OS << "extern \"C\" {\n"; @@ -1074,6 +1095,22 @@ OS << "#define __aio static inline __attribute__((__always_inline__, " "__nodebug__, __overloadable__))\n\n"; + // Add reinterpret functions. + for (auto ShortForm : { false, true } ) +for (const ReinterpretTypeInfo : Reinterprets) + for (const ReinterpretTypeInfo : Reinterprets) { +if (ShortForm) { + OS << "__aio " << From.Type << " svreinterpret_" << From.Suffix; + OS << "(" << To.Type << " op) {\n"; + OS << " return __builtin_sve_reinterpret_" << From.Suffix << "_" + << To.Suffix << "(op);\n"; + OS << "}\n\n"; +} else + OS << "#define svreinterpret_" << From.Suffix << "_" << To.Suffix + << "(...) __builtin_sve_reinterpret_" << From.Suffix << "_" + << To.Suffix << "(__VA_ARGS__)\n"; + } + SmallVector, 128> Defs; std::vector RV = Records.getAllDerivedDefinitions("Inst"); for (auto *R : RV) @@ -1148,8 +1185,16 @@ OS << "BUILTIN(__builtin_sve_" << Def->getMangledName() << ", \"" << Def->getBuiltinTypeStr() << "\", \"n\")\n"; } + + // Add reinterpret builtins + for (const ReinterpretTypeInfo : Reinterprets) +for (const ReinterpretTypeInfo : Reinterprets) + OS << "BUILTIN(__builtin_sve_reinterpret_" << From.Suffix << "_" + << To.Suffix << +", \"" << From.BuiltinType << To.BuiltinType + << "\", \"n\")\n"; + OS << "#endif\n\n"; -} + } void SVEEmitter::createCodeGenMap(raw_ostream ) { std::vector RV = Records.getAllDerivedDefinitions("Inst"); Index: clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c === --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64_be-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s + +// expected-error@* {{Big endian is currently not supported for arm_sve.h}} +#include Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c === --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c @@ -0,0 +1,960 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svint8_t test_svreinterpret_s8_s8(svint8_t op) +{ + // CHECK-LABEL: test_svreinterpret_s8_s8 + // CHECK: ret %op +
[PATCH] D78756: [SveEmitter] Add builtins for svreinterpret
efriedma added inline comments. Comment at: clang/lib/CodeGen/CGBuiltin.cpp:7880 +return Builder.CreateBitCast(Val, Ty); + } + efriedma wrote: > sdesmalen wrote: > > efriedma wrote: > > > sdesmalen wrote: > > > > efriedma wrote: > > > > > I'm vaguely suspicious this might be wrong for big-endian targets. I > > > > > mean, this isn't unreasonable, but users might be surprised if > > > > > svreinterpret isn't a no-op. > > > > For SVE the loads and stores (svld1 and svst1) are all endian safe, so > > > > no special consideration needs to be taken for big endian targets. > > > > > > > > The ACLE specifies that: > > > > > The svreinterpret functions simply reinterpret a vector of one type > > > > > as a vector of another type, without changing any of the bits. > > > "bitcast" is specified to mean "reinterpret the bits like a store+load". > > > On big-endian NEON (and, I assume, SVE), that isn't a no-op. See > > > http://llvm.org/docs/BigEndianNEON.html . > > > > > > I mean, if the answer here is "yes, svreinterpret is supposed to lower to > > > a REV", then that's fine. But I'd like to see some explciit > > > acknowledgement that that's intentional. > > Thanks for pointing out that page, but for SVE I don't think the > > svreinterpret should lower to a REV. > > > > This is probably where things are different from Neon. The ACLE SVE vectors > > such as `svint32_t` are opaque vector types and the only way to load/store > > them from/to memory is through the use of the svld1 and svst1 intrinsics > > which are endian safe (in that they use the ld1/st1 instructions that do > > endianess conversion on big endian targets). The ACLE does not expose any > > full-vector load/store (ldr/str) operations. > Like that page describes, we use ld1/st1 for big-endian NEON, to match the > LLVM IR rules for laying out a vector. If you use ld1/st1 to load/store > vectors on big-endian NEON, a bitcast is not a no-op. As far as I know, SVE > ld1/st1 is equivalent to NEON ld1/st1 in the case where vscale=1. Therefore, > on big-endian SVE, a bitcast is not a no-op. > > That leaves the following options: > > 1. svreinterpret is not a no-op. > 2. svreinterpret is not equivalent to an LLVM IR bitcast, so this patch needs > to be changed. (If you don't care about big-endian SVE right now, that's fine, but please at least leave a FIXME.) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78756/new/ https://reviews.llvm.org/D78756 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D78756: [SveEmitter] Add builtins for svreinterpret
efriedma added inline comments. Comment at: clang/lib/CodeGen/CGBuiltin.cpp:7880 +return Builder.CreateBitCast(Val, Ty); + } + sdesmalen wrote: > efriedma wrote: > > sdesmalen wrote: > > > efriedma wrote: > > > > I'm vaguely suspicious this might be wrong for big-endian targets. I > > > > mean, this isn't unreasonable, but users might be surprised if > > > > svreinterpret isn't a no-op. > > > For SVE the loads and stores (svld1 and svst1) are all endian safe, so no > > > special consideration needs to be taken for big endian targets. > > > > > > The ACLE specifies that: > > > > The svreinterpret functions simply reinterpret a vector of one type as > > > > a vector of another type, without changing any of the bits. > > "bitcast" is specified to mean "reinterpret the bits like a store+load". > > On big-endian NEON (and, I assume, SVE), that isn't a no-op. See > > http://llvm.org/docs/BigEndianNEON.html . > > > > I mean, if the answer here is "yes, svreinterpret is supposed to lower to a > > REV", then that's fine. But I'd like to see some explciit acknowledgement > > that that's intentional. > Thanks for pointing out that page, but for SVE I don't think the > svreinterpret should lower to a REV. > > This is probably where things are different from Neon. The ACLE SVE vectors > such as `svint32_t` are opaque vector types and the only way to load/store > them from/to memory is through the use of the svld1 and svst1 intrinsics > which are endian safe (in that they use the ld1/st1 instructions that do > endianess conversion on big endian targets). The ACLE does not expose any > full-vector load/store (ldr/str) operations. Like that page describes, we use ld1/st1 for big-endian NEON, to match the LLVM IR rules for laying out a vector. If you use ld1/st1 to load/store vectors on big-endian NEON, a bitcast is not a no-op. As far as I know, SVE ld1/st1 is equivalent to NEON ld1/st1 in the case where vscale=1. Therefore, on big-endian SVE, a bitcast is not a no-op. That leaves the following options: 1. svreinterpret is not a no-op. 2. svreinterpret is not equivalent to an LLVM IR bitcast, so this patch needs to be changed. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78756/new/ https://reviews.llvm.org/D78756 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D78756: [SveEmitter] Add builtins for svreinterpret
sdesmalen marked an inline comment as done. sdesmalen added inline comments. Comment at: clang/lib/CodeGen/CGBuiltin.cpp:7880 +return Builder.CreateBitCast(Val, Ty); + } + efriedma wrote: > sdesmalen wrote: > > efriedma wrote: > > > I'm vaguely suspicious this might be wrong for big-endian targets. I > > > mean, this isn't unreasonable, but users might be surprised if > > > svreinterpret isn't a no-op. > > For SVE the loads and stores (svld1 and svst1) are all endian safe, so no > > special consideration needs to be taken for big endian targets. > > > > The ACLE specifies that: > > > The svreinterpret functions simply reinterpret a vector of one type as a > > > vector of another type, without changing any of the bits. > "bitcast" is specified to mean "reinterpret the bits like a store+load". On > big-endian NEON (and, I assume, SVE), that isn't a no-op. See > http://llvm.org/docs/BigEndianNEON.html . > > I mean, if the answer here is "yes, svreinterpret is supposed to lower to a > REV", then that's fine. But I'd like to see some explciit acknowledgement > that that's intentional. Thanks for pointing out that page, but for SVE I don't think the svreinterpret should lower to a REV. This is probably where things are different from Neon. The ACLE SVE vectors such as `svint32_t` are opaque vector types and the only way to load/store them from/to memory is through the use of the svld1 and svst1 intrinsics which are endian safe (in that they use the ld1/st1 instructions that do endianess conversion on big endian targets). The ACLE does not expose any full-vector load/store (ldr/str) operations. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78756/new/ https://reviews.llvm.org/D78756 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D78756: [SveEmitter] Add builtins for svreinterpret
efriedma added inline comments. Comment at: clang/lib/CodeGen/CGBuiltin.cpp:7880 +return Builder.CreateBitCast(Val, Ty); + } + sdesmalen wrote: > efriedma wrote: > > I'm vaguely suspicious this might be wrong for big-endian targets. I mean, > > this isn't unreasonable, but users might be surprised if svreinterpret > > isn't a no-op. > For SVE the loads and stores (svld1 and svst1) are all endian safe, so no > special consideration needs to be taken for big endian targets. > > The ACLE specifies that: > > The svreinterpret functions simply reinterpret a vector of one type as a > > vector of another type, without changing any of the bits. "bitcast" is specified to mean "reinterpret the bits like a store+load". On big-endian NEON (and, I assume, SVE), that isn't a no-op. See http://llvm.org/docs/BigEndianNEON.html . I mean, if the answer here is "yes, svreinterpret is supposed to lower to a REV", then that's fine. But I'd like to see some explciit acknowledgement that that's intentional. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78756/new/ https://reviews.llvm.org/D78756 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D78756: [SveEmitter] Add builtins for svreinterpret
sdesmalen marked an inline comment as done. sdesmalen added inline comments. Comment at: clang/lib/CodeGen/CGBuiltin.cpp:7880 +return Builder.CreateBitCast(Val, Ty); + } + efriedma wrote: > I'm vaguely suspicious this might be wrong for big-endian targets. I mean, > this isn't unreasonable, but users might be surprised if svreinterpret isn't > a no-op. For SVE the loads and stores (svld1 and svst1) are all endian safe, so no special consideration needs to be taken for big endian targets. The ACLE specifies that: > The svreinterpret functions simply reinterpret a vector of one type as a > vector of another type, without changing any of the bits. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78756/new/ https://reviews.llvm.org/D78756 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D78756: [SveEmitter] Add builtins for svreinterpret
efriedma added inline comments. Comment at: clang/lib/CodeGen/CGBuiltin.cpp:7880 +return Builder.CreateBitCast(Val, Ty); + } + I'm vaguely suspicious this might be wrong for big-endian targets. I mean, this isn't unreasonable, but users might be surprised if svreinterpret isn't a no-op. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D78756/new/ https://reviews.llvm.org/D78756 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D78756: [SveEmitter] Add builtins for svreinterpret
sdesmalen created this revision. sdesmalen added reviewers: SjoerdMeijer, efriedma, ctetreau. Herald added subscribers: kristof.beyls, tschuett. Herald added a reviewer: rengolin. Herald added a project: clang. The reinterpret builtins are generated separately because they need the cross product of all types, 121 functions in total, which is inconvenient to specify in the arm_sve.td file. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D78756 Files: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c clang/utils/TableGen/SveEmitter.cpp Index: clang/utils/TableGen/SveEmitter.cpp === --- clang/utils/TableGen/SveEmitter.cpp +++ clang/utils/TableGen/SveEmitter.cpp @@ -235,6 +235,23 @@ class SVEEmitter { private: + // The reinterpret builtins are generated separately because they + // need the cross product of all types (121 functions in total), + // which is inconvenient to specify in the arm_sve.td file or + // generate in CGBuiltin.cpp. + struct ReinterpretTypeInfo { +const char *Suffix; +const char *Type; +const char *BuiltinType; + }; + SmallVector Reinterprets = { + {"s8", "svint8_t", "q16Sc"}, {"s16", "svint16_t", "q8Ss"}, + {"s32", "svint32_t", "q4Si"}, {"s64", "svint64_t", "q2SWi"}, + {"u8", "svuint8_t", "q16Uc"}, {"u16", "svuint16_t", "q8Us"}, + {"u32", "svuint32_t", "q4Ui"}, {"u64", "svuint64_t", "q2UWi"}, + {"f16", "svfloat16_t", "q8h"}, {"f32", "svfloat32_t", "q4f"}, + {"f64", "svfloat64_t", "q2d"}}; + RecordKeeper llvm::StringMap EltTypes; llvm::StringMap MemEltTypes; @@ -1053,6 +1070,22 @@ OS << "#define __aio static inline __attribute__((__always_inline__, " "__nodebug__, __overloadable__))\n\n"; + // Add reinterpret functions. + for (auto ShortForm : { false, true } ) +for (const ReinterpretTypeInfo : Reinterprets) + for (const ReinterpretTypeInfo : Reinterprets) { +if (ShortForm) { + OS << "__aio " << From.Type << " svreinterpret_" << From.Suffix; + OS << "(" << To.Type << " op) {\n"; + OS << " return __builtin_sve_reinterpret_" << From.Suffix << "_" + << To.Suffix << "(op);\n"; + OS << "}\n\n"; +} else + OS << "#define svreinterpret_" << From.Suffix << "_" << To.Suffix + << "(...) __builtin_sve_reinterpret_" << From.Suffix << "_" + << To.Suffix << "(__VA_ARGS__)\n"; + } + SmallVector, 128> Defs; std::vector RV = Records.getAllDerivedDefinitions("Inst"); for (auto *R : RV) @@ -1223,8 +1256,16 @@ OS << "BUILTIN(__builtin_sve_" << Def->getMangledName() << ", \"" << Def->getBuiltinTypeStr() << "\", \"n\")\n"; } + + // Add reinterpret builtins + for (const ReinterpretTypeInfo : Reinterprets) +for (const ReinterpretTypeInfo : Reinterprets) + OS << "BUILTIN(__builtin_sve_reinterpret_" << From.Suffix << "_" + << To.Suffix << +", \"" << From.BuiltinType << To.BuiltinType + << "\", \"n\")\n"; + OS << "#endif\n\n"; -} + } void SVEEmitter::createCodeGenMap(raw_ostream ) { std::vector RV = Records.getAllDerivedDefinitions("Inst"); Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c === --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c @@ -0,0 +1,960 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svint8_t test_svreinterpret_s8_s8(svint8_t op) +{ + // CHECK-LABEL: test_svreinterpret_s8_s8 + // CHECK: ret %op + return SVE_ACLE_FUNC(svreinterpret_s8,_s8,,)(op); +} + +svint8_t test_svreinterpret_s8_s16(svint16_t op) +{ + // CHECK-LABEL: test_svreinterpret_s8_s16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_s8,_s16,,)(op); +} + +svint8_t test_svreinterpret_s8_s32(svint32_t op) +{ + // CHECK-LABEL: test_svreinterpret_s8_s32 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_s8,_s32,,)(op); +} + +svint8_t test_svreinterpret_s8_s64(svint64_t op) +{ + // CHECK-LABEL: test_svreinterpret_s8_s64 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return