Skip to content

Commit 7a4763b

Browse files
Lancernlanza
authored andcommitted
[CIR] Add support for __builtin_bitreverse (#1386)
This PR adds CIRGen and LLVM lowering support for the `__builtin_bitreverse` family of builtin functions.
1 parent 4669855 commit 7a4763b

File tree

3 files changed

+79
-2
lines changed

3 files changed

+79
-2
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,6 +1782,36 @@ def RotateOp : CIR_Op<"rotate", [Pure, SameOperandsAndResultType]> {
17821782
}];
17831783
}
17841784

1785+
//===----------------------------------------------------------------------===//
1786+
// BitReverseOp
1787+
//===----------------------------------------------------------------------===//
1788+
1789+
def BitReverseOp : CIR_Op<"bit_reverse", [Pure, SameOperandsAndResultType]> {
1790+
let summary = "Reverse the bit pattern of the operand integer";
1791+
let description = [{
1792+
The `cir.bit_reverse` operation reverses the bit pattern of the operand
1793+
integer. Its only argument must be of unsigned integer types of width 8, 16,
1794+
32, or 64.
1795+
1796+
This operation covers the C/C++ builtin function `__builtin_bitreverse`.
1797+
1798+
Example:
1799+
1800+
```mlir
1801+
%1 = cir.bit_reverse %0 : !u32i
1802+
```
1803+
}];
1804+
1805+
let arguments = (ins AnyTypeOf<[UInt8, UInt16, UInt32, UInt64]>:$src);
1806+
let results = (outs AnyTypeOf<[UInt8, UInt16, UInt32, UInt64]>:$result);
1807+
1808+
let assemblyFormat = [{
1809+
$src `:` type($result) attr-dict
1810+
}];
1811+
1812+
let llvmOp = "BitReverseOp";
1813+
}
1814+
17851815
//===----------------------------------------------------------------------===//
17861816
// CmpThreeWayOp
17871817
//===----------------------------------------------------------------------===//

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,8 +1187,11 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
11871187
case Builtin::BI__builtin_bitreverse8:
11881188
case Builtin::BI__builtin_bitreverse16:
11891189
case Builtin::BI__builtin_bitreverse32:
1190-
case Builtin::BI__builtin_bitreverse64:
1191-
llvm_unreachable("BI__builtin_bitreverse8 like NYI");
1190+
case Builtin::BI__builtin_bitreverse64: {
1191+
mlir::Value arg = emitScalarExpr(E->getArg(0));
1192+
return RValue::get(
1193+
builder.create<cir::BitReverseOp>(getLoc(E->getSourceRange()), arg));
1194+
}
11921195

11931196
case Builtin::BI__builtin_rotateleft8:
11941197
case Builtin::BI__builtin_rotateleft16:
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
4+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
5+
6+
unsigned char bitreverse8(unsigned char value) {
7+
return __builtin_bitreverse8(value);
8+
}
9+
10+
// CIR-LABEL: @bitreverse8
11+
// CIR: %{{.+}} = cir.bit_reverse %{{.+}} : !u8i
12+
13+
// LLVM-LABEL: @bitreverse8
14+
// LLVM: %{{.+}} = call i8 @llvm.bitreverse.i8(i8 %{{.+}})
15+
16+
unsigned short bitreverse16(unsigned short value) {
17+
return __builtin_bitreverse16(value);
18+
}
19+
20+
// CIR-LABEL: @bitreverse16
21+
// CIR: %{{.+}} = cir.bit_reverse %{{.+}} : !u16i
22+
23+
// LLVM-LABEL: @bitreverse16
24+
// LLVM: %{{.+}} = call i16 @llvm.bitreverse.i16(i16 %{{.+}})
25+
26+
unsigned bitreverse32(unsigned value) {
27+
return __builtin_bitreverse32(value);
28+
}
29+
30+
// CIR-LABEL: @bitreverse32
31+
// CIR: %{{.+}} = cir.bit_reverse %{{.+}} : !u32i
32+
33+
// LLVM-LABEL: @bitreverse32
34+
// LLVM: %{{.+}} = call i32 @llvm.bitreverse.i32(i32 %{{.+}})
35+
36+
unsigned long long bitreverse64(unsigned long long value) {
37+
return __builtin_bitreverse64(value);
38+
}
39+
40+
// CIR-LABEL: @bitreverse64
41+
// CIR: %{{.+}} = cir.bit_reverse %{{.+}} : !u64i
42+
43+
// LLVM-LABEL: @bitreverse64
44+
// LLVM: %{{.+}} = call i64 @llvm.bitreverse.i64(i64 %{{.+}})

0 commit comments

Comments
 (0)