[clang] [CIR] Restore builtin switch-case order to match clang CodeGen (NFC) (PR #232635)
Steffen Larsen via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 16 00:28:53 PDT 2026
https://github.com/steffenlarsen created https://github.com/llvm/llvm-project/pull/232635
The builtin switch-case in CIRGenFunction::emitBuiltinExpr in CIR has diverged from CodeGenFunction::EmitBuiltinExpr in OGCG w.r.t. case-order.
Restore the order for consistency.
Assisted-by: Claude Opus 5.5
>From e49d8bf8e647b5e82c942725a2042d1fc7a63d95 Mon Sep 17 00:00:00 2001
From: Steffen Holst Larsen <sholstla at amd.com>
Date: Fri, 16 Oct 2026 01:58:28 -0500
Subject: [PATCH] [CIR] Restore builtin switch-case order to match clang
CodeGen (NFC)
The builtin switch-case in CIRGenFunction::emitBuiltinExpr in CIR has
diverged from CodeGenFunction::EmitBuiltinExpr in OGCG w.r.t.
case-order.
Restore the order for consistency.
Signed-off-by: Steffen Holst Larsen <sholstla at amd.com>
---
clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 689 ++++++++++++------------
1 file changed, 347 insertions(+), 342 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index d91c74e628da6..a94139cff20ff 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1343,8 +1343,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
// C stdarg builtins.
case Builtin::BI__builtin_stdarg_start:
case Builtin::BI__builtin_va_start:
- case Builtin::BI__builtin_c23_va_start:
- case Builtin::BI__va_start: {
+ case Builtin::BI__va_start:
+ case Builtin::BI__builtin_c23_va_start: {
mlir::Value vaList = builtinID == Builtin::BI__va_start
? emitScalarExpr(e->getArg(0))
: emitVAListRef(e->getArg(0)).getPointer();
@@ -1390,73 +1390,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return RValue::get(result);
}
- case Builtin::BI__assume:
- case Builtin::BI__builtin_assume: {
- if (e->getArg(0)->HasSideEffects(getContext()))
- return RValue::get(nullptr);
-
- mlir::Value argValue = emitCheckedArgForAssume(e->getArg(0));
- cir::AssumeOp::create(builder, loc, argValue, cir::AssumeBundleKind::None,
- mlir::ValueRange{});
- return RValue::get(nullptr);
- }
-
- case Builtin::BI__builtin_assume_separate_storage: {
- mlir::Value value0 = emitScalarExpr(e->getArg(0));
- mlir::Value value1 = emitScalarExpr(e->getArg(1));
- mlir::Value cond = builder.getBool(true, loc);
- cir::AssumeOp::create(builder, loc, cond,
- cir::AssumeBundleKind::SeparateStorage,
- mlir::ValueRange{value0, value1});
- return RValue::get(nullptr);
- }
-
- case Builtin::BI__arithmetic_fence: {
- assert(!cir::MissingFeatures::fastMathFlags());
- QualType argType = e->getArg(0)->getType();
- FPOptions fpFeatures = e->getFPFeaturesInEffect(getLangOpts());
- if (fpFeatures.getAllowFPReassociate() &&
- getContext().getTargetInfo().checkArithmeticFenceSupported()) {
- cgm.errorNYI(e->getSourceRange(), "__arithmetic_fence with reassocc");
- }
- if (argType->isComplexType())
- return RValue::getComplex(emitComplexExpr(e->getArg(0)));
- return RValue::get(emitScalarExpr(e->getArg(0)));
- }
-
- case Builtin::BI__builtin_assume_dereferenceable: {
- mlir::Value ptrValue = emitScalarExpr(e->getArg(0));
- mlir::Value sizeValue = emitScalarExpr(e->getArg(1));
- // The `dereferenceable` operand bundle expects a pointer-sized unsigned
- // integer; widen/narrow as needed.
- mlir::Type uintPtrTy = convertType(getContext().getUIntPtrType());
- if (sizeValue.getType() != uintPtrTy)
- sizeValue = builder.createIntCast(sizeValue, uintPtrTy);
- mlir::Value cond = builder.getBool(true, loc);
- cir::AssumeOp::create(builder, loc, cond,
- cir::AssumeBundleKind::Dereferenceable,
- mlir::ValueRange{ptrValue, sizeValue});
- return RValue::get(nullptr);
- }
-
- case Builtin::BI__builtin_assume_aligned: {
- const Expr *ptrExpr = e->getArg(0);
- mlir::Value ptrValue = emitScalarExpr(ptrExpr);
- mlir::Value offsetValue =
- (e->getNumArgs() > 2) ? emitScalarExpr(e->getArg(2)) : nullptr;
-
- std::optional<llvm::APSInt> alignment =
- e->getArg(1)->getIntegerConstantExpr(getContext());
- assert(alignment.has_value() &&
- "the second argument to __builtin_assume_aligned must be an "
- "integral constant expression");
-
- mlir::Value result =
- emitAlignmentAssumption(ptrValue, ptrExpr, ptrExpr->getExprLoc(),
- alignment->getSExtValue(), offsetValue);
- return RValue::get(result);
- }
-
case Builtin::BI__builtin_complex: {
mlir::Value real = emitScalarExpr(e->getArg(0));
mlir::Value imag = emitScalarExpr(e->getArg(1));
@@ -1464,6 +1397,17 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return RValue::getComplex(complex);
}
+ case Builtin::BI__builtin_conj:
+ case Builtin::BI__builtin_conjf:
+ case Builtin::BI__builtin_conjl:
+ case Builtin::BIconj:
+ case Builtin::BIconjf:
+ case Builtin::BIconjl: {
+ mlir::Value complex = emitComplexExpr(e->getArg(0));
+ mlir::Value conj = builder.createComplexConj(loc, complex);
+ return RValue::getComplex(conj);
+ }
+
case Builtin::BI__builtin_creal:
case Builtin::BI__builtin_crealf:
case Builtin::BI__builtin_creall:
@@ -1486,17 +1430,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return RValue::get(imag);
}
- case Builtin::BI__builtin_conj:
- case Builtin::BI__builtin_conjf:
- case Builtin::BI__builtin_conjl:
- case Builtin::BIconj:
- case Builtin::BIconjf:
- case Builtin::BIconjl: {
- mlir::Value complex = emitComplexExpr(e->getArg(0));
- mlir::Value conj = builder.createComplexConj(loc, complex);
- return RValue::getComplex(conj);
- }
-
case Builtin::BI__builtin_clrsb:
case Builtin::BI__builtin_clrsbl:
case Builtin::BI__builtin_clrsbll:
@@ -1511,127 +1444,9 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
getTarget().isCLZForZeroUndef());
case Builtin::BI__builtin_ctzg:
return emitBuiltinBitOpWithFallback<cir::BitCtzOp>(*this, e);
- case Builtin::BIstdc_trailing_zeros_uc:
- case Builtin::BIstdc_trailing_zeros_us:
- case Builtin::BIstdc_trailing_zeros_ui:
- case Builtin::BIstdc_trailing_zeros_ul:
- case Builtin::BIstdc_trailing_zeros_ull:
- case Builtin::BI__builtin_stdc_trailing_zeros:
- return emitStdcCountOp<cir::BitCtzOp>(*this, e, /*invertArg=*/false,
- /*poisonZero=*/false);
-
- case Builtin::BIstdc_leading_zeros_uc:
- case Builtin::BIstdc_leading_zeros_us:
- case Builtin::BIstdc_leading_zeros_ui:
- case Builtin::BIstdc_leading_zeros_ul:
- case Builtin::BIstdc_leading_zeros_ull:
- case Builtin::BI__builtin_stdc_leading_zeros:
- return emitStdcCountOp<cir::BitClzOp>(*this, e, /*invertArg=*/false,
- /*poisonZero=*/false);
-
- case Builtin::BIstdc_trailing_ones_uc:
- case Builtin::BIstdc_trailing_ones_us:
- case Builtin::BIstdc_trailing_ones_ui:
- case Builtin::BIstdc_trailing_ones_ul:
- case Builtin::BIstdc_trailing_ones_ull:
- case Builtin::BI__builtin_stdc_trailing_ones:
- return emitStdcCountOp<cir::BitCtzOp>(*this, e, /*invertArg=*/true,
- /*poisonZero=*/false);
-
- case Builtin::BIstdc_leading_ones_uc:
- case Builtin::BIstdc_leading_ones_us:
- case Builtin::BIstdc_leading_ones_ui:
- case Builtin::BIstdc_leading_ones_ul:
- case Builtin::BIstdc_leading_ones_ull:
- case Builtin::BI__builtin_stdc_leading_ones:
- return emitStdcCountOp<cir::BitClzOp>(*this, e, /*invertArg=*/true,
- /*poisonZero=*/false);
-
- case Builtin::BIstdc_bit_width_uc:
- case Builtin::BIstdc_bit_width_us:
- case Builtin::BIstdc_bit_width_ui:
- case Builtin::BIstdc_bit_width_ul:
- case Builtin::BIstdc_bit_width_ull:
- case Builtin::BI__builtin_stdc_bit_width:
- return emitStdcBitWidthMinus<cir::BitClzOp>(*this, e,
- /*poisonZero=*/false);
-
- case Builtin::BIstdc_count_zeros_uc:
- case Builtin::BIstdc_count_zeros_us:
- case Builtin::BIstdc_count_zeros_ui:
- case Builtin::BIstdc_count_zeros_ul:
- case Builtin::BIstdc_count_zeros_ull:
- case Builtin::BI__builtin_stdc_count_zeros:
- return emitStdcBitWidthMinus<cir::BitPopcountOp>(*this, e);
-
- case Builtin::BIstdc_count_ones_uc:
- case Builtin::BIstdc_count_ones_us:
- case Builtin::BIstdc_count_ones_ui:
- case Builtin::BIstdc_count_ones_ul:
- case Builtin::BIstdc_count_ones_ull:
- case Builtin::BI__builtin_stdc_count_ones:
- return emitStdcCountOp<cir::BitPopcountOp>(*this, e,
- /*invertArg=*/false);
-
- case Builtin::BIstdc_has_single_bit_uc:
- case Builtin::BIstdc_has_single_bit_us:
- case Builtin::BIstdc_has_single_bit_ui:
- case Builtin::BIstdc_has_single_bit_ul:
- case Builtin::BIstdc_has_single_bit_ull:
- case Builtin::BI__builtin_stdc_has_single_bit:
- return emitStdcHasSingleBit(*this, e);
-
- case Builtin::BIstdc_first_leading_zero_uc:
- case Builtin::BIstdc_first_leading_zero_us:
- case Builtin::BIstdc_first_leading_zero_ui:
- case Builtin::BIstdc_first_leading_zero_ul:
- case Builtin::BIstdc_first_leading_zero_ull:
- case Builtin::BI__builtin_stdc_first_leading_zero:
- return emitStdcFirstBit<cir::BitClzOp>(*this, e, /*invertArg=*/true,
- /*poisonZero=*/false);
-
- case Builtin::BIstdc_first_leading_one_uc:
- case Builtin::BIstdc_first_leading_one_us:
- case Builtin::BIstdc_first_leading_one_ui:
- case Builtin::BIstdc_first_leading_one_ul:
- case Builtin::BIstdc_first_leading_one_ull:
- case Builtin::BI__builtin_stdc_first_leading_one:
- return emitStdcFirstBit<cir::BitClzOp>(*this, e, /*invertArg=*/false,
- /*poisonZero=*/false);
-
- case Builtin::BIstdc_first_trailing_zero_uc:
- case Builtin::BIstdc_first_trailing_zero_us:
- case Builtin::BIstdc_first_trailing_zero_ui:
- case Builtin::BIstdc_first_trailing_zero_ul:
- case Builtin::BIstdc_first_trailing_zero_ull:
- case Builtin::BI__builtin_stdc_first_trailing_zero:
- return emitStdcFirstBit<cir::BitCtzOp>(*this, e, /*invertArg=*/true,
- /*poisonZero=*/false);
-
- case Builtin::BIstdc_first_trailing_one_uc:
- case Builtin::BIstdc_first_trailing_one_us:
- case Builtin::BIstdc_first_trailing_one_ui:
- case Builtin::BIstdc_first_trailing_one_ul:
- case Builtin::BIstdc_first_trailing_one_ull:
- case Builtin::BI__builtin_stdc_first_trailing_one:
- return emitStdcFirstBit<cir::BitCtzOp>(*this, e, /*invertArg=*/false,
- /*poisonZero=*/false);
-
- case Builtin::BIstdc_bit_ceil_uc:
- case Builtin::BIstdc_bit_ceil_us:
- case Builtin::BIstdc_bit_ceil_ui:
- case Builtin::BIstdc_bit_ceil_ul:
- case Builtin::BIstdc_bit_ceil_ull:
- case Builtin::BI__builtin_stdc_bit_ceil:
- return emitStdcBitCeil(*this, e);
-
- case Builtin::BIstdc_bit_floor_uc:
- case Builtin::BIstdc_bit_floor_us:
- case Builtin::BIstdc_bit_floor_ui:
- case Builtin::BIstdc_bit_floor_ul:
- case Builtin::BIstdc_bit_floor_ull:
- case Builtin::BI__builtin_stdc_bit_floor:
- return emitStdcBitFloor(*this, e);
+ case Builtin::BI__builtin_elementwise_ctzg:
+ cgm.errorNYI(e->getSourceRange(), "__builtin_elementwise_ctzg");
+ return RValue::get(nullptr);
case Builtin::BI__builtin_clzs:
case Builtin::BI__builtin_clz:
@@ -1642,10 +1457,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
getTarget().isCLZForZeroUndef());
case Builtin::BI__builtin_clzg:
return emitBuiltinBitOpWithFallback<cir::BitClzOp>(*this, e);
-
- case Builtin::BI__builtin_elementwise_ctzg:
- cgm.errorNYI(e->getSourceRange(), "__builtin_elementwise_ctzg");
- return RValue::get(nullptr);
case Builtin::BI__builtin_elementwise_clzg:
cgm.errorNYI(e->getSourceRange(), "__builtin_elementwise_clzg");
return RValue::get(nullptr);
@@ -1705,73 +1516,262 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
probability);
}
- auto result = cir::ExpectOp::create(builder, loc, argValue.getType(),
- argValue, expectedValue, probAttr);
- return RValue::get(result);
- }
+ auto result = cir::ExpectOp::create(builder, loc, argValue.getType(),
+ argValue, expectedValue, probAttr);
+ return RValue::get(result);
+ }
+
+ case Builtin::BI__builtin_assume_aligned: {
+ const Expr *ptrExpr = e->getArg(0);
+ mlir::Value ptrValue = emitScalarExpr(ptrExpr);
+ mlir::Value offsetValue =
+ (e->getNumArgs() > 2) ? emitScalarExpr(e->getArg(2)) : nullptr;
+
+ std::optional<llvm::APSInt> alignment =
+ e->getArg(1)->getIntegerConstantExpr(getContext());
+ assert(alignment.has_value() &&
+ "the second argument to __builtin_assume_aligned must be an "
+ "integral constant expression");
+
+ mlir::Value result =
+ emitAlignmentAssumption(ptrValue, ptrExpr, ptrExpr->getExprLoc(),
+ alignment->getSExtValue(), offsetValue);
+ return RValue::get(result);
+ }
+
+ case Builtin::BI__builtin_assume_dereferenceable: {
+ mlir::Value ptrValue = emitScalarExpr(e->getArg(0));
+ mlir::Value sizeValue = emitScalarExpr(e->getArg(1));
+ // The `dereferenceable` operand bundle expects a pointer-sized unsigned
+ // integer; widen/narrow as needed.
+ mlir::Type uintPtrTy = convertType(getContext().getUIntPtrType());
+ if (sizeValue.getType() != uintPtrTy)
+ sizeValue = builder.createIntCast(sizeValue, uintPtrTy);
+ mlir::Value cond = builder.getBool(true, loc);
+ cir::AssumeOp::create(builder, loc, cond,
+ cir::AssumeBundleKind::Dereferenceable,
+ mlir::ValueRange{ptrValue, sizeValue});
+ return RValue::get(nullptr);
+ }
+
+ case Builtin::BI__assume:
+ case Builtin::BI__builtin_assume: {
+ if (e->getArg(0)->HasSideEffects(getContext()))
+ return RValue::get(nullptr);
+
+ mlir::Value argValue = emitCheckedArgForAssume(e->getArg(0));
+ cir::AssumeOp::create(builder, loc, argValue, cir::AssumeBundleKind::None,
+ mlir::ValueRange{});
+ return RValue::get(nullptr);
+ }
+
+ case Builtin::BI__builtin_assume_separate_storage: {
+ mlir::Value value0 = emitScalarExpr(e->getArg(0));
+ mlir::Value value1 = emitScalarExpr(e->getArg(1));
+ mlir::Value cond = builder.getBool(true, loc);
+ cir::AssumeOp::create(builder, loc, cond,
+ cir::AssumeBundleKind::SeparateStorage,
+ mlir::ValueRange{value0, value1});
+ return RValue::get(nullptr);
+ }
+
+ case Builtin::BI__arithmetic_fence: {
+ assert(!cir::MissingFeatures::fastMathFlags());
+ QualType argType = e->getArg(0)->getType();
+ FPOptions fpFeatures = e->getFPFeaturesInEffect(getLangOpts());
+ if (fpFeatures.getAllowFPReassociate() &&
+ getContext().getTargetInfo().checkArithmeticFenceSupported()) {
+ cgm.errorNYI(e->getSourceRange(), "__arithmetic_fence with reassocc");
+ }
+ if (argType->isComplexType())
+ return RValue::getComplex(emitComplexExpr(e->getArg(0)));
+ return RValue::get(emitScalarExpr(e->getArg(0)));
+ }
+
+ case Builtin::BI__builtin_bswapg: {
+ mlir::Value arg = emitScalarExpr(e->getArg(0));
+ // CIR models bool as cir.bool rather than an integer, so peel it off
+ // before the cast below. Like classic codegen's i1 case, it byte-swaps
+ // to itself.
+ if (mlir::isa<cir::BoolType>(arg.getType()))
+ return RValue::get(arg);
+ auto argTy = mlir::cast<cir::IntType>(arg.getType());
+ // A single bit or a single byte byte-swaps to itself.
+ if (argTy.getWidth() == 1 || argTy.getWidth() == 8)
+ return RValue::get(arg);
+ assert(argTy.getWidth() % 16 == 0 &&
+ "__builtin_bswapg requires a single byte or a multiple of 16 bits");
+ // cir.byte_swap requires an unsigned operand. Reinterpret a signed
+ // argument as unsigned of the same width; createBuiltinBitOp casts the
+ // swapped result back to the builtin's (possibly signed) return type.
+ if (argTy.isSigned())
+ arg = builder.createIntCast(arg, builder.getUIntNTy(argTy.getWidth()));
+ return RValue::get(createBuiltinBitOp<cir::ByteSwapOp>(*this, e, arg));
+ }
+
+ case Builtin::BI__builtin_bswap16:
+ case Builtin::BI__builtin_bswap32:
+ case Builtin::BI__builtin_bswap64:
+ case Builtin::BI_byteswap_ushort:
+ case Builtin::BI_byteswap_ulong:
+ case Builtin::BI_byteswap_uint64: {
+ mlir::Value arg = emitScalarExpr(e->getArg(0));
+ return RValue::get(cir::ByteSwapOp::create(builder, loc, arg));
+ }
+
+ case Builtin::BI__builtin_bitreverse8:
+ case Builtin::BI__builtin_bitreverse16:
+ case Builtin::BI__builtin_bitreverse32:
+ case Builtin::BI__builtin_bitreverse64: {
+ mlir::Value arg = emitScalarExpr(e->getArg(0));
+ return RValue::get(cir::BitReverseOp::create(builder, loc, arg));
+ }
+
+ case Builtin::BI__builtin_rotateleft8:
+ case Builtin::BI__builtin_rotateleft16:
+ case Builtin::BI__builtin_rotateleft32:
+ case Builtin::BI__builtin_rotateleft64:
+ case Builtin::BI__builtin_stdc_rotate_left:
+ case Builtin::BIstdc_rotate_left_uc:
+ case Builtin::BIstdc_rotate_left_us:
+ case Builtin::BIstdc_rotate_left_ui:
+ case Builtin::BIstdc_rotate_left_ul:
+ case Builtin::BIstdc_rotate_left_ull:
+ return emitRotate(e, /*isRotateLeft=*/true);
+
+ case Builtin::BI__builtin_rotateright8:
+ case Builtin::BI__builtin_rotateright16:
+ case Builtin::BI__builtin_rotateright32:
+ case Builtin::BI__builtin_rotateright64:
+ case Builtin::BI__builtin_stdc_rotate_right:
+ case Builtin::BIstdc_rotate_right_uc:
+ case Builtin::BIstdc_rotate_right_us:
+ case Builtin::BIstdc_rotate_right_ui:
+ case Builtin::BIstdc_rotate_right_ul:
+ case Builtin::BIstdc_rotate_right_ull:
+ return emitRotate(e, /*isRotateLeft=*/false);
+
+ case Builtin::BIstdc_leading_zeros_uc:
+ case Builtin::BIstdc_leading_zeros_us:
+ case Builtin::BIstdc_leading_zeros_ui:
+ case Builtin::BIstdc_leading_zeros_ul:
+ case Builtin::BIstdc_leading_zeros_ull:
+ case Builtin::BI__builtin_stdc_leading_zeros:
+ return emitStdcCountOp<cir::BitClzOp>(*this, e, /*invertArg=*/false,
+ /*poisonZero=*/false);
+
+ case Builtin::BIstdc_leading_ones_uc:
+ case Builtin::BIstdc_leading_ones_us:
+ case Builtin::BIstdc_leading_ones_ui:
+ case Builtin::BIstdc_leading_ones_ul:
+ case Builtin::BIstdc_leading_ones_ull:
+ case Builtin::BI__builtin_stdc_leading_ones:
+ return emitStdcCountOp<cir::BitClzOp>(*this, e, /*invertArg=*/true,
+ /*poisonZero=*/false);
+
+ case Builtin::BIstdc_trailing_zeros_uc:
+ case Builtin::BIstdc_trailing_zeros_us:
+ case Builtin::BIstdc_trailing_zeros_ui:
+ case Builtin::BIstdc_trailing_zeros_ul:
+ case Builtin::BIstdc_trailing_zeros_ull:
+ case Builtin::BI__builtin_stdc_trailing_zeros:
+ return emitStdcCountOp<cir::BitCtzOp>(*this, e, /*invertArg=*/false,
+ /*poisonZero=*/false);
+
+ case Builtin::BIstdc_trailing_ones_uc:
+ case Builtin::BIstdc_trailing_ones_us:
+ case Builtin::BIstdc_trailing_ones_ui:
+ case Builtin::BIstdc_trailing_ones_ul:
+ case Builtin::BIstdc_trailing_ones_ull:
+ case Builtin::BI__builtin_stdc_trailing_ones:
+ return emitStdcCountOp<cir::BitCtzOp>(*this, e, /*invertArg=*/true,
+ /*poisonZero=*/false);
+
+ case Builtin::BIstdc_first_leading_zero_uc:
+ case Builtin::BIstdc_first_leading_zero_us:
+ case Builtin::BIstdc_first_leading_zero_ui:
+ case Builtin::BIstdc_first_leading_zero_ul:
+ case Builtin::BIstdc_first_leading_zero_ull:
+ case Builtin::BI__builtin_stdc_first_leading_zero:
+ return emitStdcFirstBit<cir::BitClzOp>(*this, e, /*invertArg=*/true,
+ /*poisonZero=*/false);
+
+ case Builtin::BIstdc_first_leading_one_uc:
+ case Builtin::BIstdc_first_leading_one_us:
+ case Builtin::BIstdc_first_leading_one_ui:
+ case Builtin::BIstdc_first_leading_one_ul:
+ case Builtin::BIstdc_first_leading_one_ull:
+ case Builtin::BI__builtin_stdc_first_leading_one:
+ return emitStdcFirstBit<cir::BitClzOp>(*this, e, /*invertArg=*/false,
+ /*poisonZero=*/false);
+
+ case Builtin::BIstdc_first_trailing_zero_uc:
+ case Builtin::BIstdc_first_trailing_zero_us:
+ case Builtin::BIstdc_first_trailing_zero_ui:
+ case Builtin::BIstdc_first_trailing_zero_ul:
+ case Builtin::BIstdc_first_trailing_zero_ull:
+ case Builtin::BI__builtin_stdc_first_trailing_zero:
+ return emitStdcFirstBit<cir::BitCtzOp>(*this, e, /*invertArg=*/true,
+ /*poisonZero=*/false);
+
+ case Builtin::BIstdc_first_trailing_one_uc:
+ case Builtin::BIstdc_first_trailing_one_us:
+ case Builtin::BIstdc_first_trailing_one_ui:
+ case Builtin::BIstdc_first_trailing_one_ul:
+ case Builtin::BIstdc_first_trailing_one_ull:
+ case Builtin::BI__builtin_stdc_first_trailing_one:
+ return emitStdcFirstBit<cir::BitCtzOp>(*this, e, /*invertArg=*/false,
+ /*poisonZero=*/false);
+
+ case Builtin::BIstdc_count_zeros_uc:
+ case Builtin::BIstdc_count_zeros_us:
+ case Builtin::BIstdc_count_zeros_ui:
+ case Builtin::BIstdc_count_zeros_ul:
+ case Builtin::BIstdc_count_zeros_ull:
+ case Builtin::BI__builtin_stdc_count_zeros:
+ return emitStdcBitWidthMinus<cir::BitPopcountOp>(*this, e);
- case Builtin::BI__builtin_bswapg: {
- mlir::Value arg = emitScalarExpr(e->getArg(0));
- // CIR models bool as cir.bool rather than an integer, so peel it off
- // before the cast below. Like classic codegen's i1 case, it byte-swaps
- // to itself.
- if (mlir::isa<cir::BoolType>(arg.getType()))
- return RValue::get(arg);
- auto argTy = mlir::cast<cir::IntType>(arg.getType());
- // A single bit or a single byte byte-swaps to itself.
- if (argTy.getWidth() == 1 || argTy.getWidth() == 8)
- return RValue::get(arg);
- assert(argTy.getWidth() % 16 == 0 &&
- "__builtin_bswapg requires a single byte or a multiple of 16 bits");
- // cir.byte_swap requires an unsigned operand. Reinterpret a signed
- // argument as unsigned of the same width; createBuiltinBitOp casts the
- // swapped result back to the builtin's (possibly signed) return type.
- if (argTy.isSigned())
- arg = builder.createIntCast(arg, builder.getUIntNTy(argTy.getWidth()));
- return RValue::get(createBuiltinBitOp<cir::ByteSwapOp>(*this, e, arg));
- }
+ case Builtin::BIstdc_count_ones_uc:
+ case Builtin::BIstdc_count_ones_us:
+ case Builtin::BIstdc_count_ones_ui:
+ case Builtin::BIstdc_count_ones_ul:
+ case Builtin::BIstdc_count_ones_ull:
+ case Builtin::BI__builtin_stdc_count_ones:
+ return emitStdcCountOp<cir::BitPopcountOp>(*this, e,
+ /*invertArg=*/false);
- case Builtin::BI__builtin_bswap16:
- case Builtin::BI__builtin_bswap32:
- case Builtin::BI__builtin_bswap64:
- case Builtin::BI_byteswap_ushort:
- case Builtin::BI_byteswap_ulong:
- case Builtin::BI_byteswap_uint64: {
- mlir::Value arg = emitScalarExpr(e->getArg(0));
- return RValue::get(cir::ByteSwapOp::create(builder, loc, arg));
- }
+ case Builtin::BIstdc_has_single_bit_uc:
+ case Builtin::BIstdc_has_single_bit_us:
+ case Builtin::BIstdc_has_single_bit_ui:
+ case Builtin::BIstdc_has_single_bit_ul:
+ case Builtin::BIstdc_has_single_bit_ull:
+ case Builtin::BI__builtin_stdc_has_single_bit:
+ return emitStdcHasSingleBit(*this, e);
- case Builtin::BI__builtin_bitreverse8:
- case Builtin::BI__builtin_bitreverse16:
- case Builtin::BI__builtin_bitreverse32:
- case Builtin::BI__builtin_bitreverse64: {
- mlir::Value arg = emitScalarExpr(e->getArg(0));
- return RValue::get(cir::BitReverseOp::create(builder, loc, arg));
- }
+ case Builtin::BIstdc_bit_width_uc:
+ case Builtin::BIstdc_bit_width_us:
+ case Builtin::BIstdc_bit_width_ui:
+ case Builtin::BIstdc_bit_width_ul:
+ case Builtin::BIstdc_bit_width_ull:
+ case Builtin::BI__builtin_stdc_bit_width:
+ return emitStdcBitWidthMinus<cir::BitClzOp>(*this, e,
+ /*poisonZero=*/false);
- case Builtin::BI__builtin_rotateleft8:
- case Builtin::BI__builtin_rotateleft16:
- case Builtin::BI__builtin_rotateleft32:
- case Builtin::BI__builtin_rotateleft64:
- case Builtin::BI__builtin_stdc_rotate_left:
- case Builtin::BIstdc_rotate_left_uc:
- case Builtin::BIstdc_rotate_left_us:
- case Builtin::BIstdc_rotate_left_ui:
- case Builtin::BIstdc_rotate_left_ul:
- case Builtin::BIstdc_rotate_left_ull:
- return emitRotate(e, /*isRotateLeft=*/true);
+ case Builtin::BIstdc_bit_floor_uc:
+ case Builtin::BIstdc_bit_floor_us:
+ case Builtin::BIstdc_bit_floor_ui:
+ case Builtin::BIstdc_bit_floor_ul:
+ case Builtin::BIstdc_bit_floor_ull:
+ case Builtin::BI__builtin_stdc_bit_floor:
+ return emitStdcBitFloor(*this, e);
- case Builtin::BI__builtin_rotateright8:
- case Builtin::BI__builtin_rotateright16:
- case Builtin::BI__builtin_rotateright32:
- case Builtin::BI__builtin_rotateright64:
- case Builtin::BI__builtin_stdc_rotate_right:
- case Builtin::BIstdc_rotate_right_uc:
- case Builtin::BIstdc_rotate_right_us:
- case Builtin::BIstdc_rotate_right_ui:
- case Builtin::BIstdc_rotate_right_ul:
- case Builtin::BIstdc_rotate_right_ull:
- return emitRotate(e, /*isRotateLeft=*/false);
+ case Builtin::BIstdc_bit_ceil_uc:
+ case Builtin::BIstdc_bit_ceil_us:
+ case Builtin::BIstdc_bit_ceil_ui:
+ case Builtin::BIstdc_bit_ceil_ul:
+ case Builtin::BIstdc_bit_ceil_ull:
+ case Builtin::BI__builtin_stdc_bit_ceil:
+ return emitStdcBitCeil(*this, e);
// stdc_memreverse8u8 is a no-op (single byte, nothing to swap).
case Builtin::BIstdc_memreverse8u8:
@@ -1806,55 +1806,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
break;
}
- case Builtin::BI__builtin_coro_id:
- return RValue::get(emitCoroIDBuiltinCall(e).getResult());
- case Builtin::BI__builtin_coro_alloc: {
- cir::CoroAllocOp coroAlloc = emitCoroAllocBuiltinCall(e);
- return coroAlloc ? RValue::get(coroAlloc.getResult())
- : getUndefRValue(e->getType());
- }
- case Builtin::BI__builtin_coro_begin: {
- cir::CoroBeginOp coroBeg = emitCoroBeginBuiltinCall(e);
- return coroBeg ? RValue::get(coroBeg.getResult())
- : getUndefRValue(e->getType());
- }
- case Builtin::BI__builtin_coro_end:
- return RValue::get(emitCoroEndBuiltinCall(e).getResult());
- case Builtin::BI__builtin_coro_promise:
- return RValue::get(emitCoroPromiseBuiltinCall(e).getResult());
- case Builtin::BI__builtin_coro_resume: {
- emitCoroResumeBuiltinCall(e);
- return RValue::get(nullptr);
- }
- case Builtin::BI__builtin_coro_noop:
- return RValue::get(emitCoroNoopBuiltinCall(e).getResult());
- case Builtin::BI__builtin_coro_destroy: {
- emitCoroDestroyBuiltinCall(e);
- return RValue::get(nullptr);
- }
- case Builtin::BI__builtin_coro_done:
- return RValue::get(emitCoroDoneBuiltinCall(e).getResult());
- case Builtin::BI__builtin_coro_suspend: {
- mlir::Value result = emitCoroSuspendBuiltinCall(e).getResult();
- return RValue::get(
- builder.createIntCast(result, convertType(e->getType())));
- }
- case Builtin::BI__builtin_coro_align:
- return RValue::get(emitCoroAlignBuiltinCall(e).getResult());
-
- case Builtin::BI__builtin_coro_frame: {
- return emitCoroutineFrame();
- }
- case Builtin::BI__builtin_coro_free: {
- cir::CoroFreeOp coroFree = emitCoroFreeBuiltin(e);
- return coroFree ? RValue::get(coroFree.getResult())
- : getUndefRValue(e->getType());
- }
-
- case Builtin::BI__builtin_coro_size: {
- return RValue::get(emitCoroSizeBuiltinCall(e).getResult());
- }
-
case Builtin::BI__builtin_constant_p: {
mlir::Type resultType = convertType(e->getType());
@@ -2254,6 +2205,9 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return emitBuiltinVectorReduction<cir::VecReduceOrOp>(*this, e);
case Builtin::BI__builtin_reduce_and:
return emitBuiltinVectorReduction<cir::VecReduceAndOp>(*this, e);
+ case Builtin::BI__builtin_reduce_maximum:
+ case Builtin::BI__builtin_reduce_minimum:
+ return errorBuiltinNYI(*this, e, builtinID);
case Builtin::BI__builtin_reduce_assoc_fadd:
case Builtin::BI__builtin_reduce_in_order_fadd: {
CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(*this, e);
@@ -2292,9 +2246,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
vector, fastMath);
return RValue::get(reduction.getResult());
}
- case Builtin::BI__builtin_reduce_maximum:
- case Builtin::BI__builtin_reduce_minimum:
- return errorBuiltinNYI(*this, e, builtinID);
case Builtin::BI__builtin_matrix_transpose: {
mlir::Value matrix = emitScalarExpr(e->getArg(0));
mlir::Value result = builder.createMatrixTranspose(loc, matrix);
@@ -2485,20 +2436,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
builder.createMemMove(getLoc(e->getSourceRange()), dest, src, sizeVal);
return RValue::get(nullptr);
}
- case Builtin::BI__builtin_char_memchr:
- case Builtin::BI__builtin_memchr: {
- Address srcPtr = emitPointerWithAlignment(e->getArg(0));
- mlir::Value src =
- builder.createBitcast(srcPtr.getPointer(), builder.getVoidPtrTy());
- mlir::Value pattern = emitScalarExpr(e->getArg(1));
- mlir::Value len = emitScalarExpr(e->getArg(2));
- mlir::Value res = cir::MemChrOp::create(builder, getLoc(e->getExprLoc()),
- src, pattern, len);
- // builtin_char_memchr needs its type converted to 'char', but MemChrOp is a
- // 'void' result type.
- res = builder.createBitcast(res, convertType(e->getType()));
- return RValue::get(res);
- }
case Builtin::BImemcpy:
case Builtin::BI__builtin_memcpy:
case Builtin::BImempcpy:
@@ -2521,6 +2458,21 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return RValue::get(dest.getPointer());
}
case Builtin::BI__builtin_memcpy_inline:
+ break; // Handled as library calls below.
+ case Builtin::BI__builtin_char_memchr:
+ case Builtin::BI__builtin_memchr: {
+ Address srcPtr = emitPointerWithAlignment(e->getArg(0));
+ mlir::Value src =
+ builder.createBitcast(srcPtr.getPointer(), builder.getVoidPtrTy());
+ mlir::Value pattern = emitScalarExpr(e->getArg(1));
+ mlir::Value len = emitScalarExpr(e->getArg(2));
+ mlir::Value res = cir::MemChrOp::create(builder, getLoc(e->getExprLoc()),
+ src, pattern, len);
+ // builtin_char_memchr needs its type converted to 'char', but MemChrOp is a
+ // 'void' result type.
+ res = builder.createBitcast(res, convertType(e->getType()));
+ return RValue::get(res);
+ }
case Builtin::BI__builtin___memcpy_chk:
case Builtin::BI__builtin_objc_memmove_collectable:
case Builtin::BI__builtin___memmove_chk:
@@ -2776,31 +2728,35 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
case Builtin::BI__sync_val_compare_and_swap_4:
case Builtin::BI__sync_val_compare_and_swap_8:
return RValue::get(emitAtomicCmpXchg(e, /*returnBool=*/false));
+ case Builtin::BI__sync_val_compare_and_swap_16:
+ return errorBuiltinNYI(*this, e, builtinID);
case Builtin::BI__sync_bool_compare_and_swap_1:
case Builtin::BI__sync_bool_compare_and_swap_2:
case Builtin::BI__sync_bool_compare_and_swap_4:
case Builtin::BI__sync_bool_compare_and_swap_8:
return RValue::get(emitAtomicCmpXchg(e, /*returnBool=*/true));
+ case Builtin::BI__sync_bool_compare_and_swap_16:
+ return errorBuiltinNYI(*this, e, builtinID);
case Builtin::BI__sync_swap_1:
case Builtin::BI__sync_swap_2:
case Builtin::BI__sync_swap_4:
case Builtin::BI__sync_swap_8:
return emitAtomicXchg(*this, e, cir::MemOrder::SequentiallyConsistent);
+ case Builtin::BI__sync_swap_16:
+ return errorBuiltinNYI(*this, e, builtinID);
case Builtin::BI__sync_lock_test_and_set_1:
case Builtin::BI__sync_lock_test_and_set_2:
case Builtin::BI__sync_lock_test_and_set_4:
case Builtin::BI__sync_lock_test_and_set_8:
return emitAtomicXchg(*this, e, cir::MemOrder::SequentiallyConsistent);
+ case Builtin::BI__sync_lock_test_and_set_16:
+ return errorBuiltinNYI(*this, e, builtinID);
case Builtin::BI__sync_lock_release_1:
case Builtin::BI__sync_lock_release_2:
case Builtin::BI__sync_lock_release_4:
case Builtin::BI__sync_lock_release_8:
emitAtomicLockRelease(*this, e);
return RValue::get(nullptr);
- case Builtin::BI__sync_val_compare_and_swap_16:
- case Builtin::BI__sync_bool_compare_and_swap_16:
- case Builtin::BI__sync_swap_16:
- case Builtin::BI__sync_lock_test_and_set_16:
case Builtin::BI__sync_lock_release_16:
return errorBuiltinNYI(*this, e, builtinID);
case Builtin::BI__sync_synchronize: {
@@ -2843,13 +2799,15 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
case Builtin::BI__atomic_clear:
return errorBuiltinNYI(*this, e, builtinID);
case Builtin::BI__atomic_thread_fence:
- case Builtin::BI__c11_atomic_thread_fence: {
- emitAtomicFenceOp(*this, e, cir::SyncScopeKind::System);
- return RValue::get(nullptr);
- }
case Builtin::BI__atomic_signal_fence:
+ case Builtin::BI__c11_atomic_thread_fence:
case Builtin::BI__c11_atomic_signal_fence: {
- emitAtomicFenceOp(*this, e, cir::SyncScopeKind::SingleThread);
+ cir::SyncScopeKind syncScope =
+ builtinID == Builtin::BI__atomic_signal_fence ||
+ builtinID == Builtin::BI__c11_atomic_signal_fence
+ ? cir::SyncScopeKind::SingleThread
+ : cir::SyncScopeKind::System;
+ emitAtomicFenceOp(*this, e, syncScope);
return RValue::get(nullptr);
}
case Builtin::BI__scoped_atomic_thread_fence:
@@ -3187,6 +3145,53 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return RValue::get(emitLValue(e->getArg(0)).getPointer());
case Builtin::BI__GetExceptionInfo:
case Builtin::BI__fastfail:
+ return errorBuiltinNYI(*this, e, builtinID);
+ case Builtin::BI__builtin_coro_id:
+ return RValue::get(emitCoroIDBuiltinCall(e).getResult());
+ case Builtin::BI__builtin_coro_promise:
+ return RValue::get(emitCoroPromiseBuiltinCall(e).getResult());
+ case Builtin::BI__builtin_coro_resume: {
+ emitCoroResumeBuiltinCall(e);
+ return RValue::get(nullptr);
+ }
+ case Builtin::BI__builtin_coro_frame: {
+ return emitCoroutineFrame();
+ }
+ case Builtin::BI__builtin_coro_noop:
+ return RValue::get(emitCoroNoopBuiltinCall(e).getResult());
+ case Builtin::BI__builtin_coro_free: {
+ cir::CoroFreeOp coroFree = emitCoroFreeBuiltin(e);
+ return coroFree ? RValue::get(coroFree.getResult())
+ : getUndefRValue(e->getType());
+ }
+ case Builtin::BI__builtin_coro_destroy: {
+ emitCoroDestroyBuiltinCall(e);
+ return RValue::get(nullptr);
+ }
+ case Builtin::BI__builtin_coro_done:
+ return RValue::get(emitCoroDoneBuiltinCall(e).getResult());
+ case Builtin::BI__builtin_coro_alloc: {
+ cir::CoroAllocOp coroAlloc = emitCoroAllocBuiltinCall(e);
+ return coroAlloc ? RValue::get(coroAlloc.getResult())
+ : getUndefRValue(e->getType());
+ }
+ case Builtin::BI__builtin_coro_begin: {
+ cir::CoroBeginOp coroBeg = emitCoroBeginBuiltinCall(e);
+ return coroBeg ? RValue::get(coroBeg.getResult())
+ : getUndefRValue(e->getType());
+ }
+ case Builtin::BI__builtin_coro_end:
+ return RValue::get(emitCoroEndBuiltinCall(e).getResult());
+ case Builtin::BI__builtin_coro_suspend: {
+ mlir::Value result = emitCoroSuspendBuiltinCall(e).getResult();
+ return RValue::get(
+ builder.createIntCast(result, convertType(e->getType())));
+ }
+ case Builtin::BI__builtin_coro_size: {
+ return RValue::get(emitCoroSizeBuiltinCall(e).getResult());
+ }
+ case Builtin::BI__builtin_coro_align:
+ return RValue::get(emitCoroAlignBuiltinCall(e).getResult());
case Builtin::BIread_pipe:
case Builtin::BIwrite_pipe:
case Builtin::BIreserve_read_pipe:
More information about the cfe-commits
mailing list