Skip to content

Commit 77c04bb

Browse files
authored
Implement builtin functions __builtin_ctz{s,,l,ll} (#424)
Implement the builtin functions `__builtin_ctzs`, `__builtin_ctz`, `__builtin_ctzl`, and `__builtin_ctzll` by mapping them to `math.cttz`.
1 parent ed451b3 commit 77c04bb

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

tools/cgeist/Lib/CGCall.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,17 @@ MLIRScanner::EmitClangBuiltinCallExpr(clang::CallExpr *expr) {
567567
return success(
568568
ValueCategory(castInteger(builder, loc, res, postTy), /*isRef*/ false));
569569
}
570+
case Builtin::BI__builtin_ctzs:
571+
case Builtin::BI__builtin_ctz:
572+
case Builtin::BI__builtin_ctzl:
573+
case Builtin::BI__builtin_ctzll: {
574+
auto v = Visit(expr->getArg(0));
575+
assert(!v.isReference);
576+
Value res = builder.create<math::CountTrailingZerosOp>(loc, v.val);
577+
auto postTy = getMLIRType(expr->getType()).cast<mlir::IntegerType>();
578+
return success(
579+
ValueCategory(castInteger(builder, loc, res, postTy), /*isRef*/ false));
580+
}
570581
default:
571582
break;
572583
}

tools/cgeist/Test/Verification/ctz.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: cgeist %s %stdinclude --function=* -S | FileCheck %s
2+
3+
// CHECK: func.func @do_ctzs(%[[ARG:[A-Za-z0-9_]*]]: i16) -> i32
4+
// CHECK-NEXT: %[[VAL_0:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i16
5+
// CHECK-NEXT: %[[VAL_1:[A-Za-z0-9_]*]] = arith.extui %[[VAL_0]] : i16 to i32
6+
// CHECK-NEXT: return %[[VAL_1]] : i32
7+
// CHECK-NEXT: }
8+
9+
int do_ctzs(short int i) {
10+
return __builtin_ctzs(i);
11+
}
12+
13+
// CHECK: func.func @do_ctz(%[[ARG:[A-Za-z0-9_]*]]: i32) -> i32
14+
// CHECK-NEXT: %[[VAL:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i32
15+
// CHECK-NEXT: return %[[VAL]] : i32
16+
// CHECK-NEXT: }
17+
18+
int do_ctz(int i) {
19+
return __builtin_ctz(i);
20+
}
21+
22+
// CHECK: func.func @do_ctzl(%[[ARG:[A-Za-z0-9_]*]]: i64) -> i32
23+
// CHECK-NEXT: %[[VAL_0:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i64
24+
// CHECK-NEXT: %[[VAL_1:[A-Za-z0-9_]*]] = arith.trunci %[[VAL_0]] : i64 to i32
25+
// CHECK-NEXT: return %[[VAL_1]] : i32
26+
// CHECK-NEXT: }
27+
28+
int do_ctzl(unsigned long i) {
29+
return __builtin_ctzl(i);
30+
}
31+
32+
// CHECK: func.func @do_ctzll(%[[ARG:[A-Za-z0-9_]*]]: i64) -> i32
33+
// CHECK-NEXT: %[[VAL_0:[A-Za-z0-9_]*]] = math.cttz %[[ARG]] : i64
34+
// CHECK-NEXT: %[[VAL_1:[A-Za-z0-9_]*]] = arith.trunci %[[VAL_0]] : i64 to i32
35+
// CHECK-NEXT: return %[[VAL_1]] : i32
36+
// CHECK-NEXT: }
37+
38+
int do_ctzll(unsigned long long i) {
39+
return __builtin_ctzl(i);
40+
}

0 commit comments

Comments
 (0)