[clang] [CIR][RISCV] Support rest zbb builtin codegen (PR #196704)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-clangir
Author: Jianjian Guan (jacquesguan)
Changes
Inlcude: __builtin_riscv_clz_32, __builtin_riscv_clz_64,
__builtin_riscv_ctz_32, __builtin_riscv_ctz_64.
---
Full diff: https://github.com/llvm/llvm-project/pull/196704.diff
2 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp (+19-2)
- (modified) clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c (+54-18)
``diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
b/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
index 6793e3b11cef2..ec262922be942 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
@@ -131,9 +131,26 @@ CIRGenFunction::emitRISCVBuiltinExpr(unsigned builtinID,
const CallExpr *e) {
}
// Zbb
case RISCV::BI__builtin_riscv_clz_32:
- case RISCV::BI__builtin_riscv_clz_64:
+ case RISCV::BI__builtin_riscv_clz_64: {
+mlir::Location loc = getLoc(e->getSourceRange());
+auto op = cir::BitClzOp::create(builder, loc, ops[0],
+/*poison_zero=*/false);
+mlir::Value result = op.getResult();
+if (result.getType() != returnType)
+ result = builder.createIntCast(result, returnType);
+return result;
+ }
case RISCV::BI__builtin_riscv_ctz_32:
- case RISCV::BI__builtin_riscv_ctz_64:
+ case RISCV::BI__builtin_riscv_ctz_64: {
+mlir::Location loc = getLoc(e->getSourceRange());
+auto op = cir::BitCtzOp::create(builder, loc, ops[0],
+/*poison_zero=*/false);
+mlir::Value result = op.getResult();
+if (result.getType() != returnType)
+ result = builder.createIntCast(result, returnType);
+return result;
+ }
+
// Zihintntl
case RISCV::BI__builtin_riscv_ntl_load:
case RISCV::BI__builtin_riscv_ntl_store: {
diff --git a/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
b/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
index 2b04a07ebe22c..c2ef896d75ce9 100644
--- a/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
+++ b/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
@@ -2,39 +2,75 @@
// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -fclangir -emit-cir %s
-o - | FileCheck %s --check-prefixes=CIR,CIR64
// RUN: %clang_cc1 -triple riscv32 -target-feature +zbb -fclangir -emit-llvm
%s -o - | FileCheck %s --check-prefix=LLVM
// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -fclangir -emit-llvm
%s -o - | FileCheck %s --check-prefixes=LLVM,LLVM64
-// RUN: %clang_cc1 -triple riscv32 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefix=OGCG
-// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefixes=OGCG,OGCG64
+// RUN: %clang_cc1 -triple riscv32 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefix=LLVM
+// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefixes=LLVM,LLVM64
+
+// CIR-LABEL: cir.func{{.*}} @test_builtin_orc_b_32(
+// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.orc.b" {{%.*}} : (!u32i) ->
!u32i
+// CIR: cir.return
+
+// LLVM-LABEL: @test_builtin_orc_b_32(
+// LLVM: call i32 @llvm.riscv.orc.b.i32(i32 {{%.*}})
+// LLVM: ret i32
unsigned int test_builtin_orc_b_32(unsigned int a) {
return __builtin_riscv_orc_b_32(a);
}
-#if __riscv_xlen == 64
-unsigned long long test_builtin_orc_b_64(unsigned long long a) {
- return __builtin_riscv_orc_b_64(a);
+// CIR-LABEL: cir.func{{.*}} @test_builtin_clz_32(
+// CIR: {{%.*}} = cir.clz {{%.*}} : !u32i
+// CIR: cir.return
+
+// LLVM-LABEL: @test_builtin_clz_32(
+// LLVM: call i32 @llvm.ctlz.i32(i32 {{%.*}}, i1 false)
+// LLVM: ret i32
+unsigned int test_builtin_clz_32(unsigned int a) {
+ return __builtin_riscv_clz_32(a);
}
-#endif
-// CIR-LABEL: cir.func{{.*}} @test_builtin_orc_b_32(
-// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.orc.b" {{%.*}} : (!u32i) ->
!u32i
+// CIR-LABEL: cir.func{{.*}} @test_builtin_ctz_32(
+// CIR: {{%.*}} = cir.ctz {{%.*}} : !u32i
// CIR: cir.return
+// LLVM-LABEL: @test_builtin_ctz_32(
+// LLVM: call i32 @llvm.cttz.i32(i32 {{%.*}}, i1 false)
+// LLVM: ret i32
+unsigned int test_builtin_ctz_32(unsigned int a) {
+ return __builtin_riscv_ctz_32(a);
+}
+
+#if __riscv_xlen == 64
// CIR64-LABEL: cir.func{{.*}} @test_builtin_orc_b_64(
// CIR64: {{%.*}} = cir.call_llvm_intrinsic "riscv.orc.b" {{%.*}} : (!u64i) ->
!u64i
// CIR64: cir.return
-// LLVM-LABEL: @test_builtin_orc_b_32(
-// LLVM: call i32 @llvm.riscv.orc.b.i32(i32 {{%.*}})
-// LLVM: ret i32
-
// LLVM64-LABEL: @test_builtin_orc_b_64(
// LLVM64: call i64 @llvm.riscv.orc.b.i64(i64 {{%.*}})
// LLVM64: ret i64
-// OGCG-LABEL: @test_builtin_orc_b_32(
-// OGCG: call i32 @llvm.riscv.orc.b.i32(i32 {{%.*}})
-// OGCG: ret i32
+unsigned long long test_builtin_orc_b_64(unsigned long long a) {
+ return __builtin_riscv_orc_b_64(a);
+}
-// OGCG64-LABEL: @test_builtin_orc_b_64(
-//
[clang] [CIR][RISCV] Support rest zbb builtin codegen (PR #196704)
https://github.com/jacquesguan created
https://github.com/llvm/llvm-project/pull/196704
Inlcude: __builtin_riscv_clz_32, __builtin_riscv_clz_64,
__builtin_riscv_ctz_32, __builtin_riscv_ctz_64.
>From 667d9e56a6ac51af6e191f572a05cf791bf16022 Mon Sep 17 00:00:00 2001
From: Jianjian GUAN
Date: Sat, 9 May 2026 14:47:19 +0800
Subject: [PATCH] [CIR][RISCV] Support rest zbb builtin codegen
Inlcude: __builtin_riscv_clz_32, __builtin_riscv_clz_64,
__builtin_riscv_ctz_32, __builtin_riscv_ctz_64.
---
clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp | 21 +-
.../CIR/CodeGenBuiltins/RISCV/riscv-zbb.c | 72 ++-
2 files changed, 73 insertions(+), 20 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
b/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
index 6793e3b11cef2..ec262922be942 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
@@ -131,9 +131,26 @@ CIRGenFunction::emitRISCVBuiltinExpr(unsigned builtinID,
const CallExpr *e) {
}
// Zbb
case RISCV::BI__builtin_riscv_clz_32:
- case RISCV::BI__builtin_riscv_clz_64:
+ case RISCV::BI__builtin_riscv_clz_64: {
+mlir::Location loc = getLoc(e->getSourceRange());
+auto op = cir::BitClzOp::create(builder, loc, ops[0],
+/*poison_zero=*/false);
+mlir::Value result = op.getResult();
+if (result.getType() != returnType)
+ result = builder.createIntCast(result, returnType);
+return result;
+ }
case RISCV::BI__builtin_riscv_ctz_32:
- case RISCV::BI__builtin_riscv_ctz_64:
+ case RISCV::BI__builtin_riscv_ctz_64: {
+mlir::Location loc = getLoc(e->getSourceRange());
+auto op = cir::BitCtzOp::create(builder, loc, ops[0],
+/*poison_zero=*/false);
+mlir::Value result = op.getResult();
+if (result.getType() != returnType)
+ result = builder.createIntCast(result, returnType);
+return result;
+ }
+
// Zihintntl
case RISCV::BI__builtin_riscv_ntl_load:
case RISCV::BI__builtin_riscv_ntl_store: {
diff --git a/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
b/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
index 2b04a07ebe22c..c2ef896d75ce9 100644
--- a/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
+++ b/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
@@ -2,39 +2,75 @@
// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -fclangir -emit-cir %s
-o - | FileCheck %s --check-prefixes=CIR,CIR64
// RUN: %clang_cc1 -triple riscv32 -target-feature +zbb -fclangir -emit-llvm
%s -o - | FileCheck %s --check-prefix=LLVM
// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -fclangir -emit-llvm
%s -o - | FileCheck %s --check-prefixes=LLVM,LLVM64
-// RUN: %clang_cc1 -triple riscv32 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefix=OGCG
-// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefixes=OGCG,OGCG64
+// RUN: %clang_cc1 -triple riscv32 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefix=LLVM
+// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefixes=LLVM,LLVM64
+
+// CIR-LABEL: cir.func{{.*}} @test_builtin_orc_b_32(
+// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.orc.b" {{%.*}} : (!u32i) ->
!u32i
+// CIR: cir.return
+
+// LLVM-LABEL: @test_builtin_orc_b_32(
+// LLVM: call i32 @llvm.riscv.orc.b.i32(i32 {{%.*}})
+// LLVM: ret i32
unsigned int test_builtin_orc_b_32(unsigned int a) {
return __builtin_riscv_orc_b_32(a);
}
-#if __riscv_xlen == 64
-unsigned long long test_builtin_orc_b_64(unsigned long long a) {
- return __builtin_riscv_orc_b_64(a);
+// CIR-LABEL: cir.func{{.*}} @test_builtin_clz_32(
+// CIR: {{%.*}} = cir.clz {{%.*}} : !u32i
+// CIR: cir.return
+
+// LLVM-LABEL: @test_builtin_clz_32(
+// LLVM: call i32 @llvm.ctlz.i32(i32 {{%.*}}, i1 false)
+// LLVM: ret i32
+unsigned int test_builtin_clz_32(unsigned int a) {
+ return __builtin_riscv_clz_32(a);
}
-#endif
-// CIR-LABEL: cir.func{{.*}} @test_builtin_orc_b_32(
-// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.orc.b" {{%.*}} : (!u32i) ->
!u32i
+// CIR-LABEL: cir.func{{.*}} @test_builtin_ctz_32(
+// CIR: {{%.*}} = cir.ctz {{%.*}} : !u32i
// CIR: cir.return
+// LLVM-LABEL: @test_builtin_ctz_32(
+// LLVM: call i32 @llvm.cttz.i32(i32 {{%.*}}, i1 false)
+// LLVM: ret i32
+unsigned int test_builtin_ctz_32(unsigned int a) {
+ return __builtin_riscv_ctz_32(a);
+}
+
+#if __riscv_xlen == 64
// CIR64-LABEL: cir.func{{.*}} @test_builtin_orc_b_64(
// CIR64: {{%.*}} = cir.call_llvm_intrinsic "riscv.orc.b" {{%.*}} : (!u64i) ->
!u64i
// CIR64: cir.return
-// LLVM-LABEL: @test_builtin_orc_b_32(
-// LLVM: call i32 @llvm.riscv.orc.b.i32(i32 {{%.*}})
-// LLVM: ret i32
-
// LLVM64-LABEL: @test_builtin_orc_b_64(
// LLVM64: call i64 @llvm.riscv.orc.b.i64(i64 {{%.*}})
// LLVM64: ret i64
-// OGCG-LABEL: @test_builtin_orc_b_32(
-// OGCG: ca
[clang] [CIR][RISCV] Support rest zbb builtin codegen (PR #196704)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-clang
Author: Jianjian Guan (jacquesguan)
Changes
Inlcude: __builtin_riscv_clz_32, __builtin_riscv_clz_64,
__builtin_riscv_ctz_32, __builtin_riscv_ctz_64.
---
Full diff: https://github.com/llvm/llvm-project/pull/196704.diff
2 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp (+19-2)
- (modified) clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c (+54-18)
``diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
b/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
index 6793e3b11cef2..ec262922be942 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp
@@ -131,9 +131,26 @@ CIRGenFunction::emitRISCVBuiltinExpr(unsigned builtinID,
const CallExpr *e) {
}
// Zbb
case RISCV::BI__builtin_riscv_clz_32:
- case RISCV::BI__builtin_riscv_clz_64:
+ case RISCV::BI__builtin_riscv_clz_64: {
+mlir::Location loc = getLoc(e->getSourceRange());
+auto op = cir::BitClzOp::create(builder, loc, ops[0],
+/*poison_zero=*/false);
+mlir::Value result = op.getResult();
+if (result.getType() != returnType)
+ result = builder.createIntCast(result, returnType);
+return result;
+ }
case RISCV::BI__builtin_riscv_ctz_32:
- case RISCV::BI__builtin_riscv_ctz_64:
+ case RISCV::BI__builtin_riscv_ctz_64: {
+mlir::Location loc = getLoc(e->getSourceRange());
+auto op = cir::BitCtzOp::create(builder, loc, ops[0],
+/*poison_zero=*/false);
+mlir::Value result = op.getResult();
+if (result.getType() != returnType)
+ result = builder.createIntCast(result, returnType);
+return result;
+ }
+
// Zihintntl
case RISCV::BI__builtin_riscv_ntl_load:
case RISCV::BI__builtin_riscv_ntl_store: {
diff --git a/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
b/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
index 2b04a07ebe22c..c2ef896d75ce9 100644
--- a/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
+++ b/clang/test/CIR/CodeGenBuiltins/RISCV/riscv-zbb.c
@@ -2,39 +2,75 @@
// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -fclangir -emit-cir %s
-o - | FileCheck %s --check-prefixes=CIR,CIR64
// RUN: %clang_cc1 -triple riscv32 -target-feature +zbb -fclangir -emit-llvm
%s -o - | FileCheck %s --check-prefix=LLVM
// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -fclangir -emit-llvm
%s -o - | FileCheck %s --check-prefixes=LLVM,LLVM64
-// RUN: %clang_cc1 -triple riscv32 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefix=OGCG
-// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefixes=OGCG,OGCG64
+// RUN: %clang_cc1 -triple riscv32 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefix=LLVM
+// RUN: %clang_cc1 -triple riscv64 -target-feature +zbb -emit-llvm %s -o - |
FileCheck %s --check-prefixes=LLVM,LLVM64
+
+// CIR-LABEL: cir.func{{.*}} @test_builtin_orc_b_32(
+// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.orc.b" {{%.*}} : (!u32i) ->
!u32i
+// CIR: cir.return
+
+// LLVM-LABEL: @test_builtin_orc_b_32(
+// LLVM: call i32 @llvm.riscv.orc.b.i32(i32 {{%.*}})
+// LLVM: ret i32
unsigned int test_builtin_orc_b_32(unsigned int a) {
return __builtin_riscv_orc_b_32(a);
}
-#if __riscv_xlen == 64
-unsigned long long test_builtin_orc_b_64(unsigned long long a) {
- return __builtin_riscv_orc_b_64(a);
+// CIR-LABEL: cir.func{{.*}} @test_builtin_clz_32(
+// CIR: {{%.*}} = cir.clz {{%.*}} : !u32i
+// CIR: cir.return
+
+// LLVM-LABEL: @test_builtin_clz_32(
+// LLVM: call i32 @llvm.ctlz.i32(i32 {{%.*}}, i1 false)
+// LLVM: ret i32
+unsigned int test_builtin_clz_32(unsigned int a) {
+ return __builtin_riscv_clz_32(a);
}
-#endif
-// CIR-LABEL: cir.func{{.*}} @test_builtin_orc_b_32(
-// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.orc.b" {{%.*}} : (!u32i) ->
!u32i
+// CIR-LABEL: cir.func{{.*}} @test_builtin_ctz_32(
+// CIR: {{%.*}} = cir.ctz {{%.*}} : !u32i
// CIR: cir.return
+// LLVM-LABEL: @test_builtin_ctz_32(
+// LLVM: call i32 @llvm.cttz.i32(i32 {{%.*}}, i1 false)
+// LLVM: ret i32
+unsigned int test_builtin_ctz_32(unsigned int a) {
+ return __builtin_riscv_ctz_32(a);
+}
+
+#if __riscv_xlen == 64
// CIR64-LABEL: cir.func{{.*}} @test_builtin_orc_b_64(
// CIR64: {{%.*}} = cir.call_llvm_intrinsic "riscv.orc.b" {{%.*}} : (!u64i) ->
!u64i
// CIR64: cir.return
-// LLVM-LABEL: @test_builtin_orc_b_32(
-// LLVM: call i32 @llvm.riscv.orc.b.i32(i32 {{%.*}})
-// LLVM: ret i32
-
// LLVM64-LABEL: @test_builtin_orc_b_64(
// LLVM64: call i64 @llvm.riscv.orc.b.i64(i64 {{%.*}})
// LLVM64: ret i64
-// OGCG-LABEL: @test_builtin_orc_b_32(
-// OGCG: call i32 @llvm.riscv.orc.b.i32(i32 {{%.*}})
-// OGCG: ret i32
+unsigned long long test_builtin_orc_b_64(unsigned long long a) {
+ return __builtin_riscv_orc_b_64(a);
+}
-// OGCG64-LABEL: @test_builtin_orc_b_64(
-// OG
