From 2a3a1c2dc98670c6a5dd24f8b56df17c6ccd96c3 Mon Sep 17 00:00:00 2001 From: Andi Drebes Date: Wed, 31 Jul 2024 15:57:57 +0200 Subject: [PATCH] Implement builtin functions __builtin_ctz{s,,l,ll} Implement the builtin functions `__builtin_ctzs`, `__builtin_ctz`, `__builtin_ctzl`, and `__builtin_ctzll` by mapping them to `math.cttz`. --- tools/cgeist/Lib/CGCall.cc | 11 ++++++++ tools/cgeist/Test/Verification/ctz.c | 40 ++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 tools/cgeist/Test/Verification/ctz.c diff --git a/tools/cgeist/Lib/CGCall.cc b/tools/cgeist/Lib/CGCall.cc index 51a9a1939fab..9d8fa006d2cb 100644 --- a/tools/cgeist/Lib/CGCall.cc +++ b/tools/cgeist/Lib/CGCall.cc @@ -567,6 +567,17 @@ MLIRScanner::EmitClangBuiltinCallExpr(clang::CallExpr *expr) { return success( ValueCategory(castInteger(builder, loc, res, postTy), /*isRef*/ false)); } + case Builtin::BI__builtin_ctzs: + case Builtin::BI__builtin_ctz: + case Builtin::BI__builtin_ctzl: + case Builtin::BI__builtin_ctzll: { + auto v = Visit(expr->getArg(0)); + assert(!v.isReference); + Value res = builder.create(loc, v.val); + auto postTy = getMLIRType(expr->getType()).cast(); + return success( + ValueCategory(castInteger(builder, loc, res, postTy), /*isRef*/ false)); + } default: break; } diff --git a/tools/cgeist/Test/Verification/ctz.c b/tools/cgeist/Test/Verification/ctz.c new file mode 100644 index 000000000000..d288f829557b --- /dev/null +++ b/tools/cgeist/Test/Verification/ctz.c @@ -0,0 +1,40 @@ +// RUN: cgeist %s %stdinclude --function=* -S | FileCheck %s + +// CHECK: func.func @do_ctzs(%[[ARG:[A-Za-z0-9_]*]]: i16) -> i32 +// CHECK-NEXT: %[[VAL_0:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i16 +// CHECK-NEXT: %[[VAL_1:[A-Za-z0-9_]*]] = arith.extui %[[VAL_0]] : i16 to i32 +// CHECK-NEXT: return %[[VAL_1]] : i32 +// CHECK-NEXT: } + +int do_ctzs(short int i) { + return __builtin_ctzs(i); +} + +// CHECK: func.func @do_ctz(%[[ARG:[A-Za-z0-9_]*]]: i32) -> i32 +// CHECK-NEXT: %[[VAL:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i32 +// CHECK-NEXT: return %[[VAL]] : i32 +// CHECK-NEXT: } + +int do_ctz(int i) { + return __builtin_ctz(i); +} + +// CHECK: func.func @do_ctzl(%[[ARG:[A-Za-z0-9_]*]]: i64) -> i32 +// CHECK-NEXT: %[[VAL_0:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i64 +// CHECK-NEXT: %[[VAL_1:[A-Za-z0-9_]*]] = arith.trunci %[[VAL_0]] : i64 to i32 +// CHECK-NEXT: return %[[VAL_1]] : i32 +// CHECK-NEXT: } + +int do_ctzl(unsigned long i) { + return __builtin_ctzl(i); +} + +// CHECK: func.func @do_ctzll(%[[ARG:[A-Za-z0-9_]*]]: i64) -> i32 +// CHECK-NEXT: %[[VAL_0:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i64 +// CHECK-NEXT: %[[VAL_1:[A-Za-z0-9_]*]] = arith.trunci %[[VAL_0]] : i64 to i32 +// CHECK-NEXT: return %[[VAL_1]] : i32 +// CHECK-NEXT: } + +int do_ctzll(unsigned long long i) { + return __builtin_ctzl(i); +}