[clang] [CIR] Add non-floating-point builtin intrinsics (PR #178093)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 13 12:42:26 PST 2026
https://github.com/adams381 updated https://github.com/llvm/llvm-project/pull/178093
>From 6e0249fcf97e047c8c28b0332bfdd0bdb56e765d Mon Sep 17 00:00:00 2001
From: Adam Smith <adams at nvidia.com>
Date: Mon, 26 Jan 2026 16:48:11 -0800
Subject: [PATCH 1/3] [CIR] Add non-floating-point builtin intrinsics
Add support for non-FP builtins as a follow-up to the FP math builtins PR:
- Integer abs/labs/llabs with cir.abs operation
- __builtin_unpredictable handling
- Integer elementwise abs support
- Tests: builtin-rotate.c, pred-info-builtins.c, updates to libc.c
and builtins-elementwise.c
This PR depends on #175233 (FP math builtins) and should be merged after it.
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 29 +++++
clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 39 +++++-
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 11 ++
clang/test/CIR/CodeGen/builtin-rotate.c | 118 ++++++++++++++++++
clang/test/CIR/CodeGen/builtins-elementwise.c | 12 +-
clang/test/CIR/CodeGen/libc.c | 39 ++++++
clang/test/CIR/CodeGen/pred-info-builtins.c | 72 +++++++++++
7 files changed, 317 insertions(+), 3 deletions(-)
create mode 100644 clang/test/CIR/CodeGen/builtin-rotate.c
create mode 100644 clang/test/CIR/CodeGen/pred-info-builtins.c
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index e21a4c3421a1b..5686c0890155f 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -5788,6 +5788,35 @@ def CIR_FAbsOp : CIR_UnaryFPToFPBuiltinOp<"fabs", "FAbsOp"> {
}];
}
+def CIR_AbsOp : CIR_Op<"abs", [Pure, SameOperandsAndResultType]> {
+ let summary = "Computes the absolute value of a signed integer";
+ let description = [{
+ `cir.abs` computes the absolute value of a signed integer or vector
+ of signed integers.
+
+ The `min_is_poison` attribute indicates whether the result value is a
+ poison value if the argument is statically or dynamically the minimum
+ value for the type.
+
+ Example:
+
+ ```mlir
+ %0 = cir.const #cir.int<-42> : s32i
+ %1 = cir.abs %0 min_is_poison : s32i
+ %2 = cir.abs %3 : !cir.vector<!s32i x 4>
+ ```
+ }];
+
+ let arguments = (ins
+ CIR_AnySIntOrVecOfSIntType:$src,
+ UnitAttr:$min_is_poison
+ );
+
+ let results = (outs CIR_AnySIntOrVecOfSIntType:$result);
+
+ let assemblyFormat = "$src ( `min_is_poison` $min_is_poison^ )? `:` type($src) attr-dict";
+}
+
def CIR_FloorOp : CIR_UnaryFPToFPBuiltinOp<"floor", "FloorOp"> {
let summary = "Computes the floating-point floor value";
let description = [{
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 196dab7a38dd7..8525e06af1c9d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -965,6 +965,34 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return {};
}
+ case Builtin::BIabs:
+ case Builtin::BIlabs:
+ case Builtin::BIllabs:
+ case Builtin::BI__builtin_abs:
+ case Builtin::BI__builtin_labs:
+ case Builtin::BI__builtin_llabs: {
+ bool sanitizeOverflow = sanOpts.has(SanitizerKind::SignedIntegerOverflow);
+ mlir::Value arg = emitScalarExpr(e->getArg(0));
+ mlir::Value result;
+ switch (getLangOpts().getSignedOverflowBehavior()) {
+ case LangOptions::SOB_Defined:
+ result = cir::AbsOp::create(builder, loc, arg.getType(), arg,
+ /*minIsPoison=*/false);
+ break;
+ case LangOptions::SOB_Undefined:
+ if (!sanitizeOverflow) {
+ result = cir::AbsOp::create(builder, loc, arg.getType(), arg,
+ /*minIsPoison=*/true);
+ break;
+ }
+ [[fallthrough]];
+ case LangOptions::SOB_Trapping:
+ cgm.errorNYI(e->getSourceRange(), "abs with overflow handling");
+ return RValue::get(nullptr);
+ }
+ return RValue::get(result);
+ }
+
case Builtin::BI__assume:
case Builtin::BI__builtin_assume: {
if (e->getArg(0)->HasSideEffects(getContext()))
@@ -1087,6 +1115,11 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
case Builtin::BI__builtin_popcountg:
return emitBuiltinBitOp<cir::BitPopcountOp>(*this, e);
+ case Builtin::BI__builtin_unpredictable: {
+ assert(!cir::MissingFeatures::insertBuiltinUnpredictable());
+ return RValue::get(emitScalarExpr(e->getArg(0)));
+ }
+
case Builtin::BI__builtin_expect:
case Builtin::BI__builtin_expect_with_probability: {
mlir::Value argValue = emitScalarExpr(e->getArg(0));
@@ -1381,8 +1414,10 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
bool isIntTy = cir::isIntOrVectorOfIntType(cirTy);
if (!isIntTy)
return emitUnaryFPBuiltin<cir::FAbsOp>(*this, *e);
- // Integer abs is not yet implemented
- return errorBuiltinNYI(*this, e, builtinID);
+ mlir::Value arg = emitScalarExpr(e->getArg(0));
+ mlir::Value result = cir::AbsOp::create(builder, getLoc(e->getExprLoc()),
+ arg.getType(), arg, false);
+ return RValue::get(result);
}
case Builtin::BI__builtin_elementwise_acos:
return emitUnaryMaybeConstrainedFPBuiltin<cir::ACosOp>(*this, *e);
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 28b3454d20613..b1efbe1c15094 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2278,6 +2278,17 @@ mlir::LogicalResult CIRToLLVMFAbsOpLowering::matchAndRewrite(
return mlir::success();
}
+mlir::LogicalResult CIRToLLVMAbsOpLowering::matchAndRewrite(
+ cir::AbsOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ mlir::Type resTy = typeConverter->convertType(op.getType());
+ auto absOp = mlir::LLVM::AbsOp::create(rewriter, op.getLoc(), resTy,
+ adaptor.getOperands()[0],
+ adaptor.getMinIsPoison());
+ rewriter.replaceOp(op, absOp);
+ return mlir::success();
+}
+
/// Convert the `cir.func` attributes to `llvm.func` attributes.
/// Only retain those attributes that are not constructed by
/// `LLVMFuncOp::build`. If `filterArgAttrs` is set, also filter out
diff --git a/clang/test/CIR/CodeGen/builtin-rotate.c b/clang/test/CIR/CodeGen/builtin-rotate.c
new file mode 100644
index 0000000000000..9f69e76f96148
--- /dev/null
+++ b/clang/test/CIR/CodeGen/builtin-rotate.c
@@ -0,0 +1,118 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
+
+void f() {
+// CIR-LABEL: @f
+// LLVM-LABEL: @f
+// OGCG-LABEL: @f
+ unsigned int v[4];
+ unsigned int h = __builtin_rotateleft32(v[0], 1);
+// CIR: %[[CONST:.*]] = cir.const #cir.int<1> : !u32i
+// CIR: cir.rotate left {{.*}}, %[[CONST]] : !u32i
+
+// LLVM: %[[SRC:.*]] = load i32, ptr
+// LLVM: call i32 @llvm.fshl.i32(i32 %[[SRC]], i32 %[[SRC]], i32 1)
+
+// OGCG: %[[SRC:.*]] = load i32, ptr
+// OGCG: call i32 @llvm.fshl.i32(i32 %[[SRC]], i32 %[[SRC]], i32 1)
+}
+
+unsigned char rotl8(unsigned char x, unsigned char y) {
+// CIR-LABEL: rotl8
+// CIR: cir.rotate left {{.*}}, {{.*}} : !u8i
+
+// LLVM-LABEL: rotl8
+// LLVM: [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
+
+// OGCG-LABEL: rotl8
+// OGCG: call i8 @llvm.fshl.i8(i8 {{.*}}, i8 {{.*}}, i8 {{.*}})
+ return __builtin_rotateleft8(x, y);
+}
+
+short rotl16(short x, short y) {
+// CIR-LABEL: rotl16
+// CIR: cir.rotate left {{.*}}, {{.*}} : !u16i
+
+// LLVM-LABEL: rotl16
+// LLVM: [[F:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]])
+
+// OGCG-LABEL: rotl16
+// OGCG: call i16 @llvm.fshl.i16(i16 {{.*}}, i16 {{.*}}, i16 {{.*}})
+ return __builtin_rotateleft16(x, y);
+}
+
+int rotl32(int x, unsigned int y) {
+// CIR-LABEL: rotl32
+// CIR: cir.rotate left {{.*}}, {{.*}} : !u32i
+
+// LLVM-LABEL: rotl32
+// LLVM: [[F:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+
+// OGCG-LABEL: rotl32
+// OGCG: call i32 @llvm.fshl.i32(i32 {{.*}}, i32 {{.*}}, i32 {{.*}})
+ return __builtin_rotateleft32(x, y);
+}
+
+unsigned long long rotl64(unsigned long long x, long long y) {
+// CIR-LABEL: rotl64
+// CIR: cir.rotate left {{.*}}, {{.*}} : !u64i
+
+// LLVM-LABEL: rotl64
+// LLVM: [[F:%.*]] = call i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+
+// OGCG-LABEL: rotl64
+// OGCG: call i64 @llvm.fshl.i64(i64 {{.*}}, i64 {{.*}}, i64 {{.*}})
+ return __builtin_rotateleft64(x, y);
+}
+
+char rotr8(char x, char y) {
+// CIR-LABEL: rotr8
+// CIR: cir.rotate right {{.*}}, {{.*}} : !u8i
+
+// LLVM-LABEL: rotr8
+// LLVM: [[F:%.*]] = call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
+
+// OGCG-LABEL: rotr8
+// OGCG: call i8 @llvm.fshr.i8(i8 {{.*}}, i8 {{.*}}, i8 {{.*}})
+ return __builtin_rotateright8(x, y);
+}
+
+unsigned short rotr16(unsigned short x, unsigned short y) {
+// CIR-LABEL: rotr16
+// CIR: cir.rotate right {{.*}}, {{.*}} : !u16i
+
+// LLVM-LABEL: rotr16
+// LLVM: [[F:%.*]] = call i16 @llvm.fshr.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]])
+
+// OGCG-LABEL: rotr16
+// OGCG: call i16 @llvm.fshr.i16(i16 {{.*}}, i16 {{.*}}, i16 {{.*}})
+ return __builtin_rotateright16(x, y);
+}
+
+unsigned int rotr32(unsigned int x, int y) {
+// CIR-LABEL: rotr32
+// CIR: cir.rotate right {{.*}}, {{.*}} : !u32i
+
+// LLVM-LABEL: rotr32
+// LLVM: [[F:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+
+// OGCG-LABEL: rotr32
+// OGCG: call i32 @llvm.fshr.i32(i32 {{.*}}, i32 {{.*}}, i32 {{.*}})
+ return __builtin_rotateright32(x, y);
+}
+
+long long rotr64(long long x, unsigned long long y) {
+// CIR-LABEL: rotr64
+// CIR: cir.rotate right {{.*}}, {{.*}} : !u64i
+
+// LLVM-LABEL: rotr64
+// LLVM: [[F:%.*]] = call i64 @llvm.fshr.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+
+// OGCG-LABEL: rotr64
+// OGCG: call i64 @llvm.fshr.i64(i64 {{.*}}, i64 {{.*}}, i64 {{.*}})
+ return __builtin_rotateright64(x, y);
+}
\ No newline at end of file
diff --git a/clang/test/CIR/CodeGen/builtins-elementwise.c b/clang/test/CIR/CodeGen/builtins-elementwise.c
index 3ca46e1fe3f4a..6c31ce19788d9 100644
--- a/clang/test/CIR/CodeGen/builtins-elementwise.c
+++ b/clang/test/CIR/CodeGen/builtins-elementwise.c
@@ -10,7 +10,7 @@ typedef int vint4 __attribute__((ext_vector_type(4)));
typedef float vfloat4 __attribute__((ext_vector_type(4)));
typedef double vdouble4 __attribute__((ext_vector_type(4)));
-void test_builtin_elementwise_abs(float f, double d,
+void test_builtin_elementwise_abs(vint4 vi4, int i, float f, double d,
vfloat4 vf4, vdouble4 vd4) {
// CIR-LABEL: test_builtin_elementwise_abs
// LLVM-LABEL: test_builtin_elementwise_abs
@@ -25,6 +25,16 @@ void test_builtin_elementwise_abs(float f, double d,
// OGCG: {{%.*}} = call double @llvm.fabs.f64(double {{%.*}})
d = __builtin_elementwise_abs(d);
+ // CIR: {{%.*}} = cir.abs {{%.*}} : !cir.vector<4 x !s32i>
+ // LLVM: {{%.*}} = call <4 x i32> @llvm.abs.v4i32(<4 x i32> {{%.*}}, i1 false)
+ // OGCG: {{%.*}} = call <4 x i32> @llvm.abs.v4i32(<4 x i32> {{%.*}}, i1 false)
+ vi4 = __builtin_elementwise_abs(vi4);
+
+ // CIR: {{%.*}} = cir.abs {{%.*}} : !s32
+ // LLVM: {{%.*}} = call i32 @llvm.abs.i32(i32 {{%.*}}, i1 false)
+ // OGCG: {{%.*}} = call i32 @llvm.abs.i32(i32 {{%.*}}, i1 false)
+ i = __builtin_elementwise_abs(i);
+
// CIR: {{%.*}} = cir.fabs {{%.*}} : !cir.vector<4 x !cir.float>
// LLVM: {{%.*}} = call <4 x float> @llvm.fabs.v4f32(<4 x float> {{%.*}})
// OGCG: {{%.*}} = call <4 x float> @llvm.fabs.v4f32(<4 x float> {{%.*}})
diff --git a/clang/test/CIR/CodeGen/libc.c b/clang/test/CIR/CodeGen/libc.c
index 6bd2bca33de57..1964cf5ddb06a 100644
--- a/clang/test/CIR/CodeGen/libc.c
+++ b/clang/test/CIR/CodeGen/libc.c
@@ -1,5 +1,14 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t-ogcg.ll
+// RUN: FileCheck --check-prefix=OGCG --input-file=%t-ogcg.ll %s
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir -fwrapv
+// RUN: FileCheck --check-prefix=CIR_NO_POISON --input-file=%t.cir %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll -fwrapv
+// RUN: FileCheck --check-prefix=LLVM_NO_POISON --input-file=%t.ll %s
// Note: In the final implementation, we will want these to generate
// CIR-specific libc operations. This test is just a placeholder
@@ -35,3 +44,33 @@ float testFabsf(float x) {
return fabsf(x);
// CHECK: cir.fabs %{{.+}} : !cir.float
}
+
+int abs(int);
+int testAbs(int x) {
+ return abs(x);
+ // CHECK: cir.abs %{{.+}} min_is_poison : !s32i
+ // LLVM: %{{.+}} = call i32 @llvm.abs.i32(i32 %{{.+}}, i1 true)
+ // OGCG: %{{.+}} = call i32 @llvm.abs.i32(i32 %{{.+}}, i1 true)
+ // CIR_NO_POISON: cir.abs %{{.+}} : !s32i
+ // LLVM_NO_POISON: %{{.+}} = call i32 @llvm.abs.i32(i32 %{{.+}}, i1 false)
+}
+
+long labs(long);
+long testLabs(long x) {
+ return labs(x);
+ // CHECK: cir.abs %{{.+}} min_is_poison : !s64i
+ // LLVM: %{{.+}} = call i64 @llvm.abs.i64(i64 %{{.+}}, i1 true)
+ // OGCG: %{{.+}} = call i64 @llvm.abs.i64(i64 %{{.+}}, i1 true)
+ // CIR_NO_POISON: cir.abs %{{.+}} : !s64i
+ // LLVM_NO_POISON: %{{.+}} = call i64 @llvm.abs.i64(i64 %{{.+}}, i1 false)
+}
+
+long long llabs(long long);
+long long testLlabs(long long x) {
+ return llabs(x);
+ // CHECK: cir.abs %{{.+}} min_is_poison : !s64i
+ // LLVM: %{{.+}} = call i64 @llvm.abs.i64(i64 %{{.+}}, i1 true)
+ // OGCG: %{{.+}} = call i64 @llvm.abs.i64(i64 %{{.+}}, i1 true)
+ // CIR_NO_POISON: cir.abs %{{.+}} : !s64i
+ // LLVM_NO_POISON: %{{.+}} = call i64 @llvm.abs.i64(i64 %{{.+}}, i1 false)
+}
diff --git a/clang/test/CIR/CodeGen/pred-info-builtins.c b/clang/test/CIR/CodeGen/pred-info-builtins.c
new file mode 100644
index 0000000000000..da9d42dc109f4
--- /dev/null
+++ b/clang/test/CIR/CodeGen/pred-info-builtins.c
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -O0 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s --check-prefix=CIR-O0
+// RUN: %clang_cc1 -O2 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s --check-prefix=CIR-O2
+// RUN: %clang_cc1 -O0 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s --check-prefix=LLVM
+// RUN: %clang_cc1 -O0 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=OGCG
+
+extern void __attribute__((noinline)) bar(void);
+
+void expect(int x) {
+ if (__builtin_expect(x, 0))
+ bar();
+}
+// CIR-O0: cir.func dso_local @expect
+// CIR-O0: cir.if {{%.*}} {
+// CIR-O0: cir.call @bar() : () -> ()
+
+// CIR-O2: cir.func dso_local @expect
+// CIR-O2: [[EXPECT:%.*]] = cir.expect({{.*}}, {{.*}}) : !s64i
+// CIR-O2: [[EXPECT_BOOL:%.*]] = cir.cast int_to_bool [[EXPECT]] : !s64i -> !cir.bool
+// CIR-O2: cir.if [[EXPECT_BOOL]]
+// CIR-O2: cir.call @bar() : () -> ()
+
+// LLVM-LABEL: @expect
+// LLVM: br i1 {{.*}}, label %[[THEN:.*]], label %[[END:.*]]
+// LLVM: [[THEN]]:
+// LLVM: call void @bar()
+
+// OGCG-LABEL: @expect
+// OGCG: br i1 {{.*}}, label %[[THEN:.*]], label %[[END:.*]]
+// OGCG: [[THEN]]:
+// OGCG: call void @bar()
+
+void expect_with_probability(int x) {
+ if (__builtin_expect_with_probability(x, 1, 0.8))
+ bar();
+}
+// CIR-O0: cir.func dso_local @expect_with_probability
+// CIR-O0: cir.if {{%.*}} {
+// CIR-O0: cir.call @bar() : () -> ()
+
+// CIR-O2: cir.func dso_local @expect_with_probability
+// CIR-O2: [[EXPECT:%.*]] = cir.expect({{.*}}, {{.*}}, 8.000000e-01) : !s64i
+// CIR-O2: [[EXPECT_BOOL:%.*]] = cir.cast int_to_bool [[EXPECT]] : !s64i -> !cir.bool
+// CIR-O2: cir.if [[EXPECT_BOOL]]
+// CIR-O2: cir.call @bar() : () -> ()
+
+// LLVM-LABEL: @expect_with_probability
+// LLVM: br i1 {{.*}}, label %[[THEN:.*]], label %[[END:.*]]
+// LLVM: [[THEN]]:
+// LLVM: call void @bar()
+
+// OGCG-LABEL: @expect_with_probability
+// OGCG: br i1 {{.*}}, label %[[THEN:.*]], label %[[END:.*]]
+// OGCG: [[THEN]]:
+// OGCG: call void @bar()
+
+void unpredictable(int x) {
+ if (__builtin_unpredictable(x > 1))
+ bar();
+}
+// CIR-O0: cir.func dso_local @unpredictable
+// CIR-O0: cir.if {{%.*}} {
+// CIR-O0: cir.call @bar() : () -> ()
+
+// LLVM-LABEL: @unpredictable
+// LLVM: br i1 {{.*}}, label %[[THEN:.*]], label %[[END:.*]]
+// LLVM: [[THEN]]:
+// LLVM: call void @bar()
+
+// OGCG-LABEL: @unpredictable
+// OGCG: br i1 {{.*}}, label %[[THEN:.*]], label %[[END:.*]]
+// OGCG: [[THEN]]:
+// OGCG: call void @bar()
>From c0d122679bfc6b1d2ddd1cf69842789e426d3db4 Mon Sep 17 00:00:00 2001
From: Adam Smith <adams at nvidia.com>
Date: Fri, 13 Feb 2026 10:30:54 -0800
Subject: [PATCH 2/3] [CIR] Fix pred-info-builtins no_inline
At -O0, CIR now adds no_inline to non-always_inline functions to match
classic codegen. Update the three CHECK lines in pred-info-builtins.c
to expect "cir.func no_inline dso_local" instead of "cir.func dso_local" for
@expect, @expect_with_probability, and @unpredictable so the test passes
after the noinline fix merged in #175233.
Co-authored-by: Cursor <cursoragent at cursor.com>
---
clang/test/CIR/CodeGen/pred-info-builtins.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/test/CIR/CodeGen/pred-info-builtins.c b/clang/test/CIR/CodeGen/pred-info-builtins.c
index da9d42dc109f4..f13d4afee966f 100644
--- a/clang/test/CIR/CodeGen/pred-info-builtins.c
+++ b/clang/test/CIR/CodeGen/pred-info-builtins.c
@@ -9,7 +9,7 @@ void expect(int x) {
if (__builtin_expect(x, 0))
bar();
}
-// CIR-O0: cir.func dso_local @expect
+// CIR-O0: cir.func no_inline dso_local @expect
// CIR-O0: cir.if {{%.*}} {
// CIR-O0: cir.call @bar() : () -> ()
@@ -33,7 +33,7 @@ void expect_with_probability(int x) {
if (__builtin_expect_with_probability(x, 1, 0.8))
bar();
}
-// CIR-O0: cir.func dso_local @expect_with_probability
+// CIR-O0: cir.func no_inline dso_local @expect_with_probability
// CIR-O0: cir.if {{%.*}} {
// CIR-O0: cir.call @bar() : () -> ()
@@ -57,7 +57,7 @@ void unpredictable(int x) {
if (__builtin_unpredictable(x > 1))
bar();
}
-// CIR-O0: cir.func dso_local @unpredictable
+// CIR-O0: cir.func no_inline dso_local @unpredictable
// CIR-O0: cir.if {{%.*}} {
// CIR-O0: cir.call @bar() : () -> ()
>From 3f698f4c46c20ad6c8500271f1456c670fe0c41f Mon Sep 17 00:00:00 2001
From: adams381 <adams at nvidia.com>
Date: Fri, 13 Feb 2026 14:42:17 -0600
Subject: [PATCH 3/3] Update clang/test/CIR/CodeGen/pred-info-builtins.c
This will generate code according to the O2 rules without running any LLVM optimization passes.
Co-authored-by: Andy Kaylor <akaylor at nvidia.com>
---
clang/test/CIR/CodeGen/pred-info-builtins.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/CIR/CodeGen/pred-info-builtins.c b/clang/test/CIR/CodeGen/pred-info-builtins.c
index f13d4afee966f..f05918f8d0323 100644
--- a/clang/test/CIR/CodeGen/pred-info-builtins.c
+++ b/clang/test/CIR/CodeGen/pred-info-builtins.c
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -O0 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s --check-prefix=CIR-O0
// RUN: %clang_cc1 -O2 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s --check-prefix=CIR-O2
-// RUN: %clang_cc1 -O0 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s --check-prefix=LLVM
-// RUN: %clang_cc1 -O0 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=OGCG
+// RUN: %clang_cc1 -O2 -disable-llvm-passes -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s --check-prefix=LLVM
+// RUN: %clang_cc1 -O2 -disable-llvm-passes -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=OGCG
extern void __attribute__((noinline)) bar(void);
More information about the cfe-commits
mailing list