https://github.com/Nayan0112 updated https://github.com/llvm/llvm-project/pull/234304
>From c4c6fa8c3bc71b552697191b282963ee0a1e237e Mon Sep 17 00:00:00 2001 From: Nayan112 <[email protected]> Date: Wed, 21 Oct 2026 12:04:12 +0530 Subject: [PATCH 1/4] [CIR][X86] Add MSVC bit scan builtins --- clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 51 ++++++++++++++++++++++ clang/lib/CIR/CodeGen/CIRGenFunction.h | 1 + 2 files changed, 52 insertions(+) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp index febcaa7459edb0..7540cdeb303411 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp @@ -1077,6 +1077,50 @@ mlir::Value CIRGenFunction::emitX86CpuInit(mlir::Location loc) { return builder.createCallOp(loc, initFunc, {}).getResult(); } +mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned builtinID, const CallExpr *E) { + Address indexAddress(emitPointerWithAlignment(E->getArg(0))); + mlir::Value argValue = emitScalarExpr(E->getArg(1)); + + mlir::Location loc = getLoc(E->getExprLoc()); + mlir::Type argType = argValue.getType(); + mlir::Type indexType = indexAddress.getElementType(); + mlir::Type resultType = convertType(E->getType()); + + mlir::Value argZero = builder.getNullValue(argType, loc); + mlir::Value notZero = cir::CmpOp::create( + builder, loc, cir::CmpOpKind::ne, argValue, argZero); + + cir::IfOp::create( + builder, loc, notZero, /*no else branch*/false, + [&](mlir::OpBuilder &b, mlir::Location){ + //TODO: forward or reverse scan + if (builtinID == X86::BI_BitScanForward || + builtinID == X86::BI_BitScanForward64){ + auto zeroCount = cir::BitCtzOp::create(builder, loc, argValue, true) + .getResult(); + mlir::Value castCount = builder.createCast( + loc, cir::CastKind::integral, zeroCount, indexType); + builder.createStore(loc, castCount, indexAddress, false); + } else { + unsigned argWidth = mlir::cast<cir::IntType>(argType).getWidth(); + mlir::Value argTypeLastIndex = builder.getConstantInt( + loc, indexType, argWidth - 1); + + auto zeroCount = cir::BitClzOp::create(builder, loc, argValue, true) + .getResult(); + mlir::Value castCount = builder.createCast( + loc, cir::CastKind::integral, zeroCount, indexType); + mlir::Value index = builder.createNSWSub( + loc, argTypeLastIndex, castCount); + builder.createStore(loc, index, indexAddress, false); + } + builder.createYield(loc); + } + ); + return + builder.createCast(loc, cir::CastKind::bool_to_int, notZero, resultType); +} + std::optional<mlir::Value> CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) { if (builtinID == Builtin::BI__builtin_cpu_is) @@ -1088,6 +1132,13 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) { // Handle MSVC intrinsics before argument evaluation to prevent double // evaluation. + + if (builtinID == X86::BI_BitScanForward || + builtinID == X86::BI_BitScanForward64 || + builtinID == X86::BI_BitScanReverse || + builtinID == X86::BI_BitScanReverse64) + return emitX86MSVCIntrin(builtinID, expr); + assert(!cir::MissingFeatures::msvcBuiltins()); // Find out if any arguments are required to be integer constant expressions. diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 6ca9f27748b28c..f1a196868126a4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -2553,6 +2553,7 @@ class CIRGenFunction : public CIRGenTypeCache { mlir::Value emitX86CpuSupports(mlir::Location loc, std::array<uint32_t, 4> FeatureMask); mlir::Value emitX86CpuInit(mlir::Location loc); + mlir::Value emitX86MSVCIntrin(unsigned builtinID, const CallExpr *E); std::optional<mlir::Value> emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr); >From 2b385917fe01431ebbeb70b00784b91042fde0f0 Mon Sep 17 00:00:00 2001 From: dwbh21 <[email protected]> Date: Wed, 21 Oct 2026 23:14:40 +0530 Subject: [PATCH 2/4] test added + clang formatting --- clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 52 +++++++-------- clang/test/CIR/CodeGen/ms-bitscan.c | 76 ++++++++++++++++++++++ 2 files changed, 102 insertions(+), 26 deletions(-) create mode 100644 clang/test/CIR/CodeGen/ms-bitscan.c diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp index 7540cdeb303411..6faf52659d8a60 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp @@ -1077,7 +1077,8 @@ mlir::Value CIRGenFunction::emitX86CpuInit(mlir::Location loc) { return builder.createCallOp(loc, initFunc, {}).getResult(); } -mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned builtinID, const CallExpr *E) { +mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned builtinID, + const CallExpr *E) { Address indexAddress(emitPointerWithAlignment(E->getArg(0))); mlir::Value argValue = emitScalarExpr(E->getArg(1)); @@ -1087,38 +1088,37 @@ mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned builtinID, const CallExpr mlir::Type resultType = convertType(E->getType()); mlir::Value argZero = builder.getNullValue(argType, loc); - mlir::Value notZero = cir::CmpOp::create( - builder, loc, cir::CmpOpKind::ne, argValue, argZero); - + mlir::Value notZero = + cir::CmpOp::create(builder, loc, cir::CmpOpKind::ne, argValue, argZero); + cir::IfOp::create( - builder, loc, notZero, /*no else branch*/false, - [&](mlir::OpBuilder &b, mlir::Location){ - //TODO: forward or reverse scan - if (builtinID == X86::BI_BitScanForward || - builtinID == X86::BI_BitScanForward64){ - auto zeroCount = cir::BitCtzOp::create(builder, loc, argValue, true) - .getResult(); + builder, loc, notZero, /*no else branch*/ false, + [&](mlir::OpBuilder &b, mlir::Location) { + // TODO: forward or reverse scan + if (builtinID == X86::BI_BitScanForward || + builtinID == X86::BI_BitScanForward64) { + auto zeroCount = + cir::BitCtzOp::create(builder, loc, argValue, true).getResult(); mlir::Value castCount = builder.createCast( - loc, cir::CastKind::integral, zeroCount, indexType); + loc, cir::CastKind::integral, zeroCount, indexType); builder.createStore(loc, castCount, indexAddress, false); } else { unsigned argWidth = mlir::cast<cir::IntType>(argType).getWidth(); - mlir::Value argTypeLastIndex = builder.getConstantInt( - loc, indexType, argWidth - 1); - - auto zeroCount = cir::BitClzOp::create(builder, loc, argValue, true) - .getResult(); + mlir::Value argTypeLastIndex = + builder.getConstantInt(loc, indexType, argWidth - 1); + + auto zeroCount = + cir::BitClzOp::create(builder, loc, argValue, true).getResult(); mlir::Value castCount = builder.createCast( - loc, cir::CastKind::integral, zeroCount, indexType); - mlir::Value index = builder.createNSWSub( - loc, argTypeLastIndex, castCount); + loc, cir::CastKind::integral, zeroCount, indexType); + mlir::Value index = + builder.createNSWSub(loc, argTypeLastIndex, castCount); builder.createStore(loc, index, indexAddress, false); } - builder.createYield(loc); - } - ); - return - builder.createCast(loc, cir::CastKind::bool_to_int, notZero, resultType); + builder.createYield(loc); + }); + return builder.createCast(loc, cir::CastKind::bool_to_int, notZero, + resultType); } std::optional<mlir::Value> @@ -1137,7 +1137,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) { builtinID == X86::BI_BitScanForward64 || builtinID == X86::BI_BitScanReverse || builtinID == X86::BI_BitScanReverse64) - return emitX86MSVCIntrin(builtinID, expr); + return emitX86MSVCIntrin(builtinID, expr); assert(!cir::MissingFeatures::msvcBuiltins()); diff --git a/clang/test/CIR/CodeGen/ms-bitscan.c b/clang/test/CIR/CodeGen/ms-bitscan.c new file mode 100644 index 00000000000000..4ecacce2e4b4c5 --- /dev/null +++ b/clang/test/CIR/CodeGen/ms-bitscan.c @@ -0,0 +1,76 @@ +// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions \ +// RUN: -Wno-implicit-function-declaration -fclangir \ +// RUN: -triple x86_64-unknown-linux -emit-cir -o %t.cir %s +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s + +#ifdef __LP64__ +#define LONG int +#else +#define LONG long +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned char test_BitScanForward(unsigned LONG *Index, unsigned LONG Mask) { + return _BitScanForward(Index, Mask); +} + +// CIR-LABEL: cir.func{{.*}}@test_BitScanForward +// CIR: [[ZERO_FWD:%.*]] = cir.const #cir.int<0> : !u32i +// CIR: [[NONZERO_FWD:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD]] : !u32i +// CIR: cir.if [[NONZERO_FWD]] { +// CIR: cir.ctz {{%.*}} poison_zero : !u32i +// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i> +// CIR: cir.cast bool_to_int [[NONZERO_FWD]] : !cir.bool -> !u8i + +unsigned char test_BitScanReverse(unsigned LONG *Index, unsigned LONG Mask) { + return _BitScanReverse(Index, Mask); +} + +// CIR-LABEL: cir.func{{.*}}@test_BitScanReverse +// CIR: [[ZERO_REV:%.*]] = cir.const #cir.int<0> : !u32i +// CIR: [[NONZERO_REV:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV]] : !u32i +// CIR: cir.if [[NONZERO_REV]] { +// CIR: cir.const #cir.int<31> : !u32i +// CIR: cir.clz {{%.*}} poison_zero : !u32i +// CIR: cir.sub nsw {{%.*}}, {{%.*}} : !u32i +// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i> +// CIR: cir.cast bool_to_int [[NONZERO_REV]] : !cir.bool -> !u8i + +#if defined(__x86_64__) +unsigned char test_BitScanForward64(unsigned LONG *Index, + unsigned __int64 Mask) { + return _BitScanForward64(Index, Mask); +} + +// CIR-LABEL: cir.func{{.*}}@test_BitScanForward64 +// CIR: [[ZERO_FWD64:%.*]] = cir.const #cir.int<0> : !u64i +// CIR: [[NONZERO_FWD64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_FWD64]] : !u64i +// CIR: cir.if [[NONZERO_FWD64]] { +// CIR: cir.ctz {{%.*}} poison_zero : !u64i +// CIR: cir.cast integral {{%.*}} : !u64i -> !u32i +// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i> +// CIR: cir.cast bool_to_int [[NONZERO_FWD64]] : !cir.bool -> !u8i + +unsigned char test_BitScanReverse64(unsigned LONG *Index, + unsigned __int64 Mask) { + return _BitScanReverse64(Index, Mask); +} + +// CIR-LABEL: cir.func{{.*}}@test_BitScanReverse64 +// CIR: [[ZERO_REV64:%.*]] = cir.const #cir.int<0> : !u64i +// CIR: [[NONZERO_REV64:%.*]] = cir.cmp ne {{%.*}}, [[ZERO_REV64]] : !u64i +// CIR: cir.if [[NONZERO_REV64]] { +// CIR: cir.const #cir.int<63> : !u32i +// CIR: cir.clz {{%.*}} poison_zero : !u64i +// CIR: cir.cast integral {{%.*}} : !u64i -> !u32i +// CIR: cir.sub nsw {{%.*}}, {{%.*}} : !u32i +// CIR: cir.store align(4) {{%.*}}, {{%.*}} : !u32i, !cir.ptr<!u32i> +// CIR: cir.cast bool_to_int [[NONZERO_REV64]] : !cir.bool -> !u8i +#endif + +#ifdef __cplusplus +} +#endif \ No newline at end of file >From defd4578b0336383b47f18090d77f082f8b23a1f Mon Sep 17 00:00:00 2001 From: dwbh21 <[email protected]> Date: Wed, 21 Oct 2026 23:19:56 +0530 Subject: [PATCH 3/4] removed auto --- clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp index 6faf52659d8a60..e0ccde3b4705cb 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp @@ -1097,7 +1097,7 @@ mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned builtinID, // TODO: forward or reverse scan if (builtinID == X86::BI_BitScanForward || builtinID == X86::BI_BitScanForward64) { - auto zeroCount = + mlir::Value zeroCount = cir::BitCtzOp::create(builder, loc, argValue, true).getResult(); mlir::Value castCount = builder.createCast( loc, cir::CastKind::integral, zeroCount, indexType); @@ -1107,7 +1107,7 @@ mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned builtinID, mlir::Value argTypeLastIndex = builder.getConstantInt(loc, indexType, argWidth - 1); - auto zeroCount = + mlir::Value zeroCount = cir::BitClzOp::create(builder, loc, argValue, true).getResult(); mlir::Value castCount = builder.createCast( loc, cir::CastKind::integral, zeroCount, indexType); >From b126c47b6a8bf0d3480eaa2ccbc758a266d56b89 Mon Sep 17 00:00:00 2001 From: Nayan112 <[email protected]> Date: Thu, 22 Oct 2026 13:00:47 +0530 Subject: [PATCH 4/4] [CIR][X86] Share MSVC intrinsic translation with CodeGen --- .../include/clang/CodeGenUtils/TargetUtils.h | 50 ++++++++++ clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 99 ++++++++++--------- clang/lib/CIR/CodeGen/CIRGenFunction.h | 4 +- clang/lib/CodeGen/CGBuiltin.h | 45 --------- clang/lib/CodeGen/CodeGenFunction.h | 3 +- clang/lib/CodeGen/TargetBuiltins/X86.cpp | 38 +------ clang/lib/CodeGenUtils/TargetUtils.cpp | 39 ++++++++ 7 files changed, 148 insertions(+), 130 deletions(-) diff --git a/clang/include/clang/CodeGenUtils/TargetUtils.h b/clang/include/clang/CodeGenUtils/TargetUtils.h index 1d1ada1644efc8..ff3ee3488278a4 100644 --- a/clang/include/clang/CodeGenUtils/TargetUtils.h +++ b/clang/include/clang/CodeGenUtils/TargetUtils.h @@ -17,6 +17,7 @@ #include "clang/Basic/BitmaskEnum.h" #include <cstdint> +#include <optional> namespace llvm { class Triple; @@ -63,6 +64,55 @@ bool hasExtraNeonArgument(unsigned BuiltinID); /// Helper method to check if the underlying ABI is AAPCS bool isAAPCS(const TargetInfo &TargetInfo); +//===----------------------------------------------------------------------===// +// X86 +//===----------------------------------------------------------------------===// +enum class MSVCIntrin { + _BitScanForward, + _BitScanReverse, + _InterlockedAnd, + _InterlockedCompareExchange, + _InterlockedDecrement, + _InterlockedExchange, + _InterlockedExchangeAdd, + _InterlockedExchangeSub, + _InterlockedIncrement, + _InterlockedOr, + _InterlockedXor, + _InterlockedExchangeAdd_acq, + _InterlockedExchangeAdd_rel, + _InterlockedExchangeAdd_nf, + _InterlockedExchange_acq, + _InterlockedExchange_rel, + _InterlockedExchange_nf, + _InterlockedCompareExchange_acq, + _InterlockedCompareExchange_rel, + _InterlockedCompareExchange_nf, + _InterlockedCompareExchange128, + _InterlockedCompareExchange128_acq, + _InterlockedCompareExchange128_rel, + _InterlockedCompareExchange128_nf, + _InterlockedOr_acq, + _InterlockedOr_rel, + _InterlockedOr_nf, + _InterlockedXor_acq, + _InterlockedXor_rel, + _InterlockedXor_nf, + _InterlockedAnd_acq, + _InterlockedAnd_rel, + _InterlockedAnd_nf, + _InterlockedIncrement_acq, + _InterlockedIncrement_rel, + _InterlockedIncrement_nf, + _InterlockedDecrement_acq, + _InterlockedDecrement_rel, + _InterlockedDecrement_nf, + __fastfail, +}; + +std::optional<MSVCIntrin> +translateX86ToMsvcIntrin(unsigned BuiltinID); + //===----------------------------------------------------------------------===// // AMDGPU //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp index e0ccde3b4705cb..74199ae87bc532 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp @@ -24,6 +24,7 @@ #include "clang/CIR/Dialect/IR/CIRAttrs.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" #include "clang/CIR/MissingFeatures.h" +#include "clang/CodeGenUtils/TargetUtils.h" #include "llvm/ADT/Sequence.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/TargetParser/X86TargetParser.h" @@ -1077,48 +1078,54 @@ mlir::Value CIRGenFunction::emitX86CpuInit(mlir::Location loc) { return builder.createCallOp(loc, initFunc, {}).getResult(); } -mlir::Value CIRGenFunction::emitX86MSVCIntrin(unsigned builtinID, +mlir::Value CIRGenFunction::emitX86MSVCIntrin(MSVCIntrin builtinID, const CallExpr *E) { - Address indexAddress(emitPointerWithAlignment(E->getArg(0))); - mlir::Value argValue = emitScalarExpr(E->getArg(1)); - - mlir::Location loc = getLoc(E->getExprLoc()); - mlir::Type argType = argValue.getType(); - mlir::Type indexType = indexAddress.getElementType(); - mlir::Type resultType = convertType(E->getType()); - - mlir::Value argZero = builder.getNullValue(argType, loc); - mlir::Value notZero = - cir::CmpOp::create(builder, loc, cir::CmpOpKind::ne, argValue, argZero); - - cir::IfOp::create( - builder, loc, notZero, /*no else branch*/ false, - [&](mlir::OpBuilder &b, mlir::Location) { - // TODO: forward or reverse scan - if (builtinID == X86::BI_BitScanForward || - builtinID == X86::BI_BitScanForward64) { - mlir::Value zeroCount = - cir::BitCtzOp::create(builder, loc, argValue, true).getResult(); - mlir::Value castCount = builder.createCast( - loc, cir::CastKind::integral, zeroCount, indexType); - builder.createStore(loc, castCount, indexAddress, false); - } else { - unsigned argWidth = mlir::cast<cir::IntType>(argType).getWidth(); - mlir::Value argTypeLastIndex = - builder.getConstantInt(loc, indexType, argWidth - 1); - - mlir::Value zeroCount = - cir::BitClzOp::create(builder, loc, argValue, true).getResult(); - mlir::Value castCount = builder.createCast( - loc, cir::CastKind::integral, zeroCount, indexType); - mlir::Value index = - builder.createNSWSub(loc, argTypeLastIndex, castCount); - builder.createStore(loc, index, indexAddress, false); - } - builder.createYield(loc); - }); - return builder.createCast(loc, cir::CastKind::bool_to_int, notZero, - resultType); + switch (builtinID) { + case MSVCIntrin::_BitScanForward: + case MSVCIntrin::_BitScanReverse: { + Address indexAddress(emitPointerWithAlignment(E->getArg(0))); + mlir::Value argValue = emitScalarExpr(E->getArg(1)); + + mlir::Location loc = getLoc(E->getExprLoc()); + mlir::Type argType = argValue.getType(); + mlir::Type indexType = indexAddress.getElementType(); + mlir::Type resultType = convertType(E->getType()); + + mlir::Value argZero = builder.getNullValue(argType, loc); + mlir::Value notZero = + cir::CmpOp::create(builder, loc, cir::CmpOpKind::ne, argValue, argZero); + + cir::IfOp::create( + builder, loc, notZero, /*no else branch*/ false, + [&](mlir::OpBuilder &b, mlir::Location) { + if (builtinID == MSVCIntrin::_BitScanForward) { + mlir::Value zeroCount = + cir::BitCtzOp::create(builder, loc, argValue, true).getResult(); + mlir::Value castCount = builder.createCast( + loc, cir::CastKind::integral, zeroCount, indexType); + builder.createStore(loc, castCount, indexAddress, false); + } else { + unsigned argWidth = mlir::cast<cir::IntType>(argType).getWidth(); + mlir::Value argTypeLastIndex = + builder.getConstantInt(loc, indexType, argWidth - 1); + + mlir::Value zeroCount = + cir::BitClzOp::create(builder, loc, argValue, true).getResult(); + mlir::Value castCount = builder.createCast( + loc, cir::CastKind::integral, zeroCount, indexType); + mlir::Value index = + builder.createNSWSub(loc, argTypeLastIndex, castCount); + builder.createStore(loc, index, indexAddress, false); + } + builder.createYield(loc); + }); + return builder.createCast(loc, cir::CastKind::bool_to_int, notZero, + resultType); + } + default: + cgm.errorNYI(E->getExprLoc(), "MSVC intrinsic"); + return {}; + } } std::optional<mlir::Value> @@ -1133,13 +1140,9 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) { // Handle MSVC intrinsics before argument evaluation to prevent double // evaluation. - if (builtinID == X86::BI_BitScanForward || - builtinID == X86::BI_BitScanForward64 || - builtinID == X86::BI_BitScanReverse || - builtinID == X86::BI_BitScanReverse64) - return emitX86MSVCIntrin(builtinID, expr); - - assert(!cir::MissingFeatures::msvcBuiltins()); + if (std::optional<MSVCIntrin> MsvcIntId = + CodeGenUtils::translateX86ToMsvcIntrin(builtinID)) + return emitX86MSVCIntrin(*MsvcIntId, expr); // Find out if any arguments are required to be integer constant expressions. assert(!cir::MissingFeatures::handleBuiltinICEArguments()); diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index f1a196868126a4..1e9641023d6b4d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -37,6 +37,7 @@ #include "clang/CIR/MissingFeatures.h" #include "clang/CIR/TypeEvaluationKind.h" #include "clang/CodeGenUtils/StmtUtils.h" +#include "clang/CodeGenUtils/TargetUtils.h" #include "llvm/ADT/ScopedHashTable.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" @@ -2553,7 +2554,8 @@ class CIRGenFunction : public CIRGenTypeCache { mlir::Value emitX86CpuSupports(mlir::Location loc, std::array<uint32_t, 4> FeatureMask); mlir::Value emitX86CpuInit(mlir::Location loc); - mlir::Value emitX86MSVCIntrin(unsigned builtinID, const CallExpr *E); + using MSVCIntrin = CodeGenUtils::MSVCIntrin; + mlir::Value emitX86MSVCIntrin(MSVCIntrin builtinID, const CallExpr *E); std::optional<mlir::Value> emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr); diff --git a/clang/lib/CodeGen/CGBuiltin.h b/clang/lib/CodeGen/CGBuiltin.h index 394b397fde6a9f..ddc324dbcac125 100644 --- a/clang/lib/CodeGen/CGBuiltin.h +++ b/clang/lib/CodeGen/CGBuiltin.h @@ -11,51 +11,6 @@ #include "CodeGenFunction.h" -// Many of MSVC builtins are on x64, ARM and AArch64; to avoid repeating code, -// we handle them here. -enum class clang::CodeGen::CodeGenFunction::MSVCIntrin { - _BitScanForward, - _BitScanReverse, - _InterlockedAnd, - _InterlockedCompareExchange, - _InterlockedDecrement, - _InterlockedExchange, - _InterlockedExchangeAdd, - _InterlockedExchangeSub, - _InterlockedIncrement, - _InterlockedOr, - _InterlockedXor, - _InterlockedExchangeAdd_acq, - _InterlockedExchangeAdd_rel, - _InterlockedExchangeAdd_nf, - _InterlockedExchange_acq, - _InterlockedExchange_rel, - _InterlockedExchange_nf, - _InterlockedCompareExchange_acq, - _InterlockedCompareExchange_rel, - _InterlockedCompareExchange_nf, - _InterlockedCompareExchange128, - _InterlockedCompareExchange128_acq, - _InterlockedCompareExchange128_rel, - _InterlockedCompareExchange128_nf, - _InterlockedOr_acq, - _InterlockedOr_rel, - _InterlockedOr_nf, - _InterlockedXor_acq, - _InterlockedXor_rel, - _InterlockedXor_nf, - _InterlockedAnd_acq, - _InterlockedAnd_rel, - _InterlockedAnd_nf, - _InterlockedIncrement_acq, - _InterlockedIncrement_rel, - _InterlockedIncrement_nf, - _InterlockedDecrement_acq, - _InterlockedDecrement_rel, - _InterlockedDecrement_nf, - __fastfail, -}; - // Emit a simple intrinsic that has N scalar arguments and a return type // matching the argument type. It is assumed that only the first argument is // overloaded. diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 00294ad547d5ec..3bbe632be939a8 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -35,6 +35,7 @@ #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/TargetInfo.h" +#include "clang/CodeGenUtils/TargetUtils.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/MapVector.h" @@ -5083,7 +5084,7 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::AtomicOrdering &AO, llvm::SyncScope::ID &SSID); - enum class MSVCIntrin; + using MSVCIntrin = CodeGenUtils::MSVCIntrin; llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E); llvm::Value *EmitBuiltinAvailable(const VersionTuple &Version); diff --git a/clang/lib/CodeGen/TargetBuiltins/X86.cpp b/clang/lib/CodeGen/TargetBuiltins/X86.cpp index e9b7e28eba31ce..acf63d414c16c9 100644 --- a/clang/lib/CodeGen/TargetBuiltins/X86.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/X86.cpp @@ -12,6 +12,7 @@ #include "CGBuiltin.h" #include "clang/Basic/TargetBuiltins.h" +#include "clang/CodeGenUtils/TargetUtils.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/IntrinsicsX86.h" #include "llvm/TargetParser/X86TargetParser.h" @@ -20,40 +21,6 @@ using namespace clang; using namespace CodeGen; using namespace llvm; -static std::optional<CodeGenFunction::MSVCIntrin> -translateX86ToMsvcIntrin(unsigned BuiltinID) { - using MSVCIntrin = CodeGenFunction::MSVCIntrin; - switch (BuiltinID) { - default: - return std::nullopt; - case clang::X86::BI_BitScanForward: - case clang::X86::BI_BitScanForward64: - return MSVCIntrin::_BitScanForward; - case clang::X86::BI_BitScanReverse: - case clang::X86::BI_BitScanReverse64: - return MSVCIntrin::_BitScanReverse; - case clang::X86::BI_InterlockedAnd64: - return MSVCIntrin::_InterlockedAnd; - case clang::X86::BI_InterlockedCompareExchange128: - return MSVCIntrin::_InterlockedCompareExchange128; - case clang::X86::BI_InterlockedExchange64: - return MSVCIntrin::_InterlockedExchange; - case clang::X86::BI_InterlockedExchangeAdd64: - return MSVCIntrin::_InterlockedExchangeAdd; - case clang::X86::BI_InterlockedExchangeSub64: - return MSVCIntrin::_InterlockedExchangeSub; - case clang::X86::BI_InterlockedOr64: - return MSVCIntrin::_InterlockedOr; - case clang::X86::BI_InterlockedXor64: - return MSVCIntrin::_InterlockedXor; - case clang::X86::BI_InterlockedDecrement64: - return MSVCIntrin::_InterlockedDecrement; - case clang::X86::BI_InterlockedIncrement64: - return MSVCIntrin::_InterlockedIncrement; - } - llvm_unreachable("must return from switch"); -} - // Convert the mask from an integer type to a vector of i1. static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask, unsigned NumElts) { @@ -792,7 +759,8 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, // Handle MSVC intrinsics before argument evaluation to prevent double // evaluation. - if (std::optional<MSVCIntrin> MsvcIntId = translateX86ToMsvcIntrin(BuiltinID)) + if (std::optional<CodeGenUtils::MSVCIntrin> MsvcIntId = + CodeGenUtils::translateX86ToMsvcIntrin(BuiltinID)) return EmitMSVCBuiltinExpr(*MsvcIntId, E); SmallVector<Value*, 4> Ops; diff --git a/clang/lib/CodeGenUtils/TargetUtils.cpp b/clang/lib/CodeGenUtils/TargetUtils.cpp index c2ddc7ec69da4b..67258190102167 100644 --- a/clang/lib/CodeGenUtils/TargetUtils.cpp +++ b/clang/lib/CodeGenUtils/TargetUtils.cpp @@ -84,6 +84,45 @@ bool isAAPCS(const TargetInfo &TargetInfo) { return TargetInfo.getABI().starts_with("aapcs"); } +//===----------------------------------------------------------------------===// +// X86 +//===----------------------------------------------------------------------===// + +// Many of MSVC builtins are on x64, ARM and AArch64; to avoid repeating code, +// we handle them here. +std::optional<MSVCIntrin> +translateX86ToMsvcIntrin(unsigned BuiltinID) { + switch (BuiltinID) { + default: + return std::nullopt; + case clang::X86::BI_BitScanForward: + case clang::X86::BI_BitScanForward64: + return MSVCIntrin::_BitScanForward; + case clang::X86::BI_BitScanReverse: + case clang::X86::BI_BitScanReverse64: + return MSVCIntrin::_BitScanReverse; + case clang::X86::BI_InterlockedAnd64: + return MSVCIntrin::_InterlockedAnd; + case clang::X86::BI_InterlockedCompareExchange128: + return MSVCIntrin::_InterlockedCompareExchange128; + case clang::X86::BI_InterlockedExchange64: + return MSVCIntrin::_InterlockedExchange; + case clang::X86::BI_InterlockedExchangeAdd64: + return MSVCIntrin::_InterlockedExchangeAdd; + case clang::X86::BI_InterlockedExchangeSub64: + return MSVCIntrin::_InterlockedExchangeSub; + case clang::X86::BI_InterlockedOr64: + return MSVCIntrin::_InterlockedOr; + case clang::X86::BI_InterlockedXor64: + return MSVCIntrin::_InterlockedXor; + case clang::X86::BI_InterlockedDecrement64: + return MSVCIntrin::_InterlockedDecrement; + case clang::X86::BI_InterlockedIncrement64: + return MSVCIntrin::_InterlockedIncrement; + } + llvm_unreachable("must return from switch"); +} + //===----------------------------------------------------------------------===// // AMDGPU //===----------------------------------------------------------------------===// _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
