[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-11 Thread LLVM Continuous Integration via cfe-commits

llvm-ci wrote:

LLVM Buildbot has detected a new failure on builder `llvm-clang-aarch64-darwin` 
running on `doug-worker-4` while building `clang` at step 6 
"test-build-unified-tree-check-all".

Full details are available at: 
https://lab.llvm.org/buildbot/#/builders/190/builds/23350


Here is the relevant piece of the build log for the reference

```
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
 TEST 'Clang-Unit :: ./AllClangUnitTests/15/48' FAILED 

Script(shard):
--
GTEST_OUTPUT=json:/Users/buildbot/buildbot-root/aarch64-darwin/build/tools/clang/unittests/./AllClangUnitTests-Clang-Unit-70875-15-48.json
 GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=48 GTEST_SHARD_INDEX=15 
/Users/buildbot/buildbot-root/aarch64-darwin/build/tools/clang/unittests/./AllClangUnitTests
--

Script:
--
/Users/buildbot/buildbot-root/aarch64-darwin/build/tools/clang/unittests/./AllClangUnitTests
 --gtest_filter=DirectoryWatcherTest.AddFiles
--
/Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp:257:
 Failure
Value of: WaitForExpectedStateResult.wait_for(EventualResultTimeout) == 
std::future_status::ready
  Actual: false
Expected: true
The expected result state wasn't reached before the time-out.

/Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp:260:
 Failure
Value of: TestConsumer.result().has_value()
  Actual: false
Expected: true


/Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp:257
Value of: WaitForExpectedStateResult.wait_for(EventualResultTimeout) == 
std::future_status::ready
  Actual: false
Expected: true
The expected result state wasn't reached before the time-out.

/Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp:260
Value of: TestConsumer.result().has_value()
  Actual: false
Expected: true






```



https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-11 Thread Sirui Mu via cfe-commits

https://github.com/Lancern closed 
https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-11 Thread Sirui Mu via cfe-commits

Lancern wrote:

I'm going to merge this and I'll send another patch to resolve the various nits 
in the comments.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-11 Thread Sirui Mu via cfe-commits


@@ -2661,6 +2661,45 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse",
+ CIR_UIntOfWidths<[8, 16, 32, 64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse(%0 : !u32i): !u32i
+```
+  }];
+}
+
+def ByteSwapOp : CIR_BitOpBase<"bit.byte_swap", CIR_UIntOfWidths<[16, 32, 
64]>> {
+  let summary = "Reverse the bytes in the object representation of the 
operand";
+  let description = [{
+The `cir.bswap` operation takes an integer as operand, reverse the bytes in
+the object representation of the operand integer, and returns the result.
+
+The operand integer must be an unsigned integer. Its widths must be either
+16, 32, or 64.
+
+Example:
+
+```mlir
+// %0 = 0x12345678
+%0 = cir.const #cir.int<305419896> : !u32i
+
+// %1 should be 0x78563412
+%1 = cir.bit.bswap(%0 : !u32i) : !u32i

Lancern wrote:

Changed its name to `cir.byte_swap`.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-11 Thread Sirui Mu via cfe-commits

https://github.com/Lancern updated 
https://github.com/llvm/llvm-project/pull/147200

>From fb556207b6a0504e0b767dd655ae5df146a70f30 Mon Sep 17 00:00:00 2001
From: Sirui Mu 
Date: Mon, 7 Jul 2025 00:45:48 +0800
Subject: [PATCH] [CIR] Add bit reverse and byte reverse operations

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 39 
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp   | 36 +---
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 16 
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   | 20 
 clang/test/CIR/CodeGen/builtin_bit.cpp| 91 +++
 5 files changed, 191 insertions(+), 11 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 6529f1386599c..cdbe3c51c8d5f 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2661,6 +2661,45 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse",
+ CIR_UIntOfWidths<[8, 16, 32, 64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse(%0 : !u32i): !u32i
+```
+  }];
+}
+
+def ByteSwapOp : CIR_BitOpBase<"byte_swap", CIR_UIntOfWidths<[16, 32, 64]>> {
+  let summary = "Reverse the bytes in the object representation of the 
operand";
+  let description = [{
+The `cir.byte_swap` operation takes an integer as operand, reverse the 
bytes
+in the object representation of the operand integer, and returns the 
result.
+
+The operand integer must be an unsigned integer. Its widths must be either
+16, 32, or 64.
+
+Example:
+
+```mlir
+// %0 = 0x12345678
+%0 = cir.const #cir.int<305419896> : !u32i
+
+// %1 should be 0x78563412
+%1 = cir.byte_swap(%0 : !u32i) : !u32i
+```
+  }];
+}
+
 
//===--===//
 // Assume Operations
 
//===--===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index fb046533a91b8..25be6f35df501 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -60,15 +60,15 @@ static RValue emitBuiltinBitOp(CIRGenFunction &cgf, const 
CallExpr *e,
 RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned 
builtinID,
const CallExpr *e,
ReturnValueSlot returnValue) {
+  mlir::Location loc = getLoc(e->getSourceRange());
+
   // See if we can constant fold this builtin.  If so, don't emit it at all.
   // TODO: Extend this handling to all builtin calls that we can constant-fold.
   Expr::EvalResult result;
   if (e->isPRValue() && e->EvaluateAsRValue(result, cgm.getASTContext()) &&
   !result.hasSideEffects()) {
-if (result.Val.isInt()) {
-  return RValue::get(builder.getConstInt(getLoc(e->getSourceRange()),
- result.Val.getInt()));
-}
+if (result.Val.isInt())
+  return RValue::get(builder.getConstInt(loc, result.Val.getInt()));
 if (result.Val.isFloat()) {
   // Note: we are using result type of CallExpr to determine the type of
   // the constant. Classic codegen uses the result value to determine the
@@ -76,8 +76,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, 
unsigned builtinID,
   // hard to imagine a builtin function evaluates to a value that
   // over/underflows its own defined type.
   mlir::Type type = convertType(e->getType());
-  return RValue::get(builder.getConstFP(getLoc(e->getExprLoc()), type,
-result.Val.getFloat()));
+  return RValue::get(builder.getConstFP(loc, type, result.Val.getFloat()));
 }
   }
 
@@ -101,8 +100,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   assert(!cir::MissingFeatures::builtinCallMathErrno());
   assert(!cir::MissingFeatures::builtinCall());
 
-  mlir::Location loc = getLoc(e->getExprLoc());
-
   switch (builtinIDIfNoAsmLabel) {
   default:
 break;
@@ -185,11 +182,28 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   probability);
 }
 
-auto result = builder.create(getLoc(e->getSourceRange()),
-argValue.getType(), argValue,
-expectedValue, probAttr);
+auto result = builder.create(
+   

[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-10 Thread Andy Kaylor via cfe-commits


@@ -2661,6 +2661,45 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse",
+ CIR_UIntOfWidths<[8, 16, 32, 64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse(%0 : !u32i): !u32i
+```
+  }];
+}
+
+def ByteSwapOp : CIR_BitOpBase<"bit.byte_swap", CIR_UIntOfWidths<[16, 32, 
64]>> {
+  let summary = "Reverse the bytes in the object representation of the 
operand";
+  let description = [{
+The `cir.bswap` operation takes an integer as operand, reverse the bytes in
+the object representation of the operand integer, and returns the result.
+
+The operand integer must be an unsigned integer. Its widths must be either
+16, 32, or 64.
+
+Example:
+
+```mlir
+// %0 = 0x12345678
+%0 = cir.const #cir.int<305419896> : !u32i
+
+// %1 should be 0x78563412
+%1 = cir.bit.bswap(%0 : !u32i) : !u32i

andykaylor wrote:

This is out of sync now.

@xlauko Based on your other comments, I got the impression that you would like 
these to be `cir.bitreverse` and `cir.bswap`. Is that correct? If so, that 
makes sense to me, and I don't see a reason to merge these with the `.bit` 
prefix only to remove it in a subsequent change when the prefix is removed from 
other bit operations.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-10 Thread Sirui Mu via cfe-commits


@@ -2661,6 +2661,45 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse",
+ CIR_UIntOfWidths<[8, 16, 32, 64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse(%0 : !u32i): !u32i
+```
+  }];
+}
+
+def ByteSwapOp : CIR_BitOpBase<"bit.bswap", CIR_UIntOfWidths<[16, 32, 64]>> {

Lancern wrote:

> Can we maybe spell it out, `bit.byte_swap`?

Updated.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-10 Thread Sirui Mu via cfe-commits

https://github.com/Lancern updated 
https://github.com/llvm/llvm-project/pull/147200

>From cf2bf0bf66f22e8fdc35baf8d4176aa5af6588d2 Mon Sep 17 00:00:00 2001
From: Sirui Mu 
Date: Mon, 7 Jul 2025 00:45:48 +0800
Subject: [PATCH 1/2] [CIR] Add bit reverse and byte reverse operations

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 39 
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp   | 36 +---
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 16 
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   | 20 
 clang/test/CIR/CodeGen/builtin_bit.cpp| 91 +++
 5 files changed, 191 insertions(+), 11 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 6529f1386599c..48b54c8335b19 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2661,6 +2661,45 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse",
+ CIR_UIntOfWidths<[8, 16, 32, 64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse(%0 : !u32i): !u32i
+```
+  }];
+}
+
+def ByteSwapOp : CIR_BitOpBase<"bit.bswap", CIR_UIntOfWidths<[16, 32, 64]>> {
+  let summary = "Reverse the bytes in the object representation of the 
operand";
+  let description = [{
+The `cir.bswap` operation takes an integer as operand, reverse the bytes in
+the object representation of the operand integer, and returns the result.
+
+The operand integer must be an unsigned integer. Its widths must be either
+16, 32, or 64.
+
+Example:
+
+```mlir
+// %0 = 0x12345678
+%0 = cir.const #cir.int<305419896> : !u32i
+
+// %1 should be 0x78563412
+%1 = cir.bit.bswap(%0 : !u32i) : !u32i
+```
+  }];
+}
+
 
//===--===//
 // Assume Operations
 
//===--===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index fb046533a91b8..25be6f35df501 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -60,15 +60,15 @@ static RValue emitBuiltinBitOp(CIRGenFunction &cgf, const 
CallExpr *e,
 RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned 
builtinID,
const CallExpr *e,
ReturnValueSlot returnValue) {
+  mlir::Location loc = getLoc(e->getSourceRange());
+
   // See if we can constant fold this builtin.  If so, don't emit it at all.
   // TODO: Extend this handling to all builtin calls that we can constant-fold.
   Expr::EvalResult result;
   if (e->isPRValue() && e->EvaluateAsRValue(result, cgm.getASTContext()) &&
   !result.hasSideEffects()) {
-if (result.Val.isInt()) {
-  return RValue::get(builder.getConstInt(getLoc(e->getSourceRange()),
- result.Val.getInt()));
-}
+if (result.Val.isInt())
+  return RValue::get(builder.getConstInt(loc, result.Val.getInt()));
 if (result.Val.isFloat()) {
   // Note: we are using result type of CallExpr to determine the type of
   // the constant. Classic codegen uses the result value to determine the
@@ -76,8 +76,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, 
unsigned builtinID,
   // hard to imagine a builtin function evaluates to a value that
   // over/underflows its own defined type.
   mlir::Type type = convertType(e->getType());
-  return RValue::get(builder.getConstFP(getLoc(e->getExprLoc()), type,
-result.Val.getFloat()));
+  return RValue::get(builder.getConstFP(loc, type, result.Val.getFloat()));
 }
   }
 
@@ -101,8 +100,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   assert(!cir::MissingFeatures::builtinCallMathErrno());
   assert(!cir::MissingFeatures::builtinCall());
 
-  mlir::Location loc = getLoc(e->getExprLoc());
-
   switch (builtinIDIfNoAsmLabel) {
   default:
 break;
@@ -185,11 +182,28 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   probability);
 }
 
-auto result = builder.create(getLoc(e->getSourceRange()),
-argValue.getType(), argValue,
-expectedValue, probAttr);
+auto result = builder.create(
+ 

[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-10 Thread Sirui Mu via cfe-commits


@@ -2661,6 +2661,45 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse",
+ CIR_UIntOfWidths<[8, 16, 32, 64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse(%0 : !u32i): !u32i
+```
+  }];
+}
+
+def ByteSwapOp : CIR_BitOpBase<"bit.bswap", CIR_UIntOfWidths<[16, 32, 64]>> {

Lancern wrote:

> For the same reason, I’d like to eliminate the bit. prefix entirely and use 
> the builtin names directly, like bitreverse (This can be, and probably should 
> be done as separate PR).

I'll send a separate PR for this after this PR lands.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-09 Thread Henrich Lauko via cfe-commits


@@ -2661,6 +2661,45 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse",
+ CIR_UIntOfWidths<[8, 16, 32, 64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse(%0 : !u32i): !u32i
+```
+  }];
+}
+
+def ByteSwapOp : CIR_BitOpBase<"bit.bswap", CIR_UIntOfWidths<[16, 32, 64]>> {

xlauko wrote:

Same here — I’d also prefer to keep the names as close as possible to Clang 
builtins. Using similar names reduces cognitive load and makes it easier to 
trace things through the entire pipeline.

For the same reason, I’d like to eliminate the `bit.` prefix entirely and use 
the builtin names directly, like `bitreverse` (This can be, and probably should 
be done as separate PR). I tend to interpret dot-separated names as namespaces, 
so using them just for readability feels a bit off. Grouping things like 
`complex.` or `libc.` makes sense, as they are in a way subdialects, but when 
the goal is simply improved readability, I’d lean toward using underscores 
instead in general.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-09 Thread Sirui Mu via cfe-commits


@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse %0 : !u32i
+```
+  }];
+}
+
+//===--===//
+// ByteswapOp
+//===--===//
+
+def ByteSwapOp : CIR_Op<"bswap", [Pure, SameOperandsAndResultType]> {

Lancern wrote:

Updated. Also the mnemonic is updated to `cir.bit.bswap` to match the naming 
convention for `CIR_BitOpBase`.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-09 Thread Sirui Mu via cfe-commits

https://github.com/Lancern updated 
https://github.com/llvm/llvm-project/pull/147200

>From cf2bf0bf66f22e8fdc35baf8d4176aa5af6588d2 Mon Sep 17 00:00:00 2001
From: Sirui Mu 
Date: Mon, 7 Jul 2025 00:45:48 +0800
Subject: [PATCH] [CIR] Add bit reverse and byte reverse operations

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 39 
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp   | 36 +---
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 16 
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   | 20 
 clang/test/CIR/CodeGen/builtin_bit.cpp| 91 +++
 5 files changed, 191 insertions(+), 11 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 6529f1386599c..48b54c8335b19 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2661,6 +2661,45 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse",
+ CIR_UIntOfWidths<[8, 16, 32, 64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse(%0 : !u32i): !u32i
+```
+  }];
+}
+
+def ByteSwapOp : CIR_BitOpBase<"bit.bswap", CIR_UIntOfWidths<[16, 32, 64]>> {
+  let summary = "Reverse the bytes in the object representation of the 
operand";
+  let description = [{
+The `cir.bswap` operation takes an integer as operand, reverse the bytes in
+the object representation of the operand integer, and returns the result.
+
+The operand integer must be an unsigned integer. Its widths must be either
+16, 32, or 64.
+
+Example:
+
+```mlir
+// %0 = 0x12345678
+%0 = cir.const #cir.int<305419896> : !u32i
+
+// %1 should be 0x78563412
+%1 = cir.bit.bswap(%0 : !u32i) : !u32i
+```
+  }];
+}
+
 
//===--===//
 // Assume Operations
 
//===--===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index fb046533a91b8..25be6f35df501 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -60,15 +60,15 @@ static RValue emitBuiltinBitOp(CIRGenFunction &cgf, const 
CallExpr *e,
 RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned 
builtinID,
const CallExpr *e,
ReturnValueSlot returnValue) {
+  mlir::Location loc = getLoc(e->getSourceRange());
+
   // See if we can constant fold this builtin.  If so, don't emit it at all.
   // TODO: Extend this handling to all builtin calls that we can constant-fold.
   Expr::EvalResult result;
   if (e->isPRValue() && e->EvaluateAsRValue(result, cgm.getASTContext()) &&
   !result.hasSideEffects()) {
-if (result.Val.isInt()) {
-  return RValue::get(builder.getConstInt(getLoc(e->getSourceRange()),
- result.Val.getInt()));
-}
+if (result.Val.isInt())
+  return RValue::get(builder.getConstInt(loc, result.Val.getInt()));
 if (result.Val.isFloat()) {
   // Note: we are using result type of CallExpr to determine the type of
   // the constant. Classic codegen uses the result value to determine the
@@ -76,8 +76,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, 
unsigned builtinID,
   // hard to imagine a builtin function evaluates to a value that
   // over/underflows its own defined type.
   mlir::Type type = convertType(e->getType());
-  return RValue::get(builder.getConstFP(getLoc(e->getExprLoc()), type,
-result.Val.getFloat()));
+  return RValue::get(builder.getConstFP(loc, type, result.Val.getFloat()));
 }
   }
 
@@ -101,8 +100,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   assert(!cir::MissingFeatures::builtinCallMathErrno());
   assert(!cir::MissingFeatures::builtinCall());
 
-  mlir::Location loc = getLoc(e->getExprLoc());
-
   switch (builtinIDIfNoAsmLabel) {
   default:
 break;
@@ -185,11 +182,28 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   probability);
 }
 
-auto result = builder.create(getLoc(e->getSourceRange()),
-argValue.getType(), argValue,
-expectedValue, probAttr);
+auto result = builder.create(
+l

[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Sirui Mu via cfe-commits


@@ -190,6 +190,26 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
 expectedValue, probAttr);
 return RValue::get(result);
   }
+
+  case Builtin::BI__builtin_bswap16:
+  case Builtin::BI__builtin_bswap32:
+  case Builtin::BI__builtin_bswap64:
+  case Builtin::BI_byteswap_ushort:
+  case Builtin::BI_byteswap_ulong:
+  case Builtin::BI_byteswap_uint64: {
+mlir::Value arg = emitScalarExpr(e->getArg(0));
+return RValue::get(
+builder.create(getLoc(e->getSourceRange()), arg));

Lancern wrote:

Updated.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Sirui Mu via cfe-commits

https://github.com/Lancern updated 
https://github.com/llvm/llvm-project/pull/147200

>From 2dc9775f797f944cb0f12f68bc914a0b4bb89609 Mon Sep 17 00:00:00 2001
From: Sirui Mu 
Date: Mon, 7 Jul 2025 00:45:48 +0800
Subject: [PATCH] [CIR] Add bit reverse and byte reverse operations

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 49 ++
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp   | 36 +---
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 16 
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   | 20 
 clang/test/CIR/CodeGen/builtin_bit.cpp| 91 +++
 5 files changed, 201 insertions(+), 11 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 6529f1386599c..c74bbb7dc88cd 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse(%0 : !u32i): !u32i
+```
+  }];
+}
+
+//===--===//
+// ByteSwapOp
+//===--===//
+
+def ByteSwapOp : CIR_Op<"bswap", [Pure, SameOperandsAndResultType]> {
+  let summary = "Reverse the bytes in the object representation of the 
operand";
+  let description = [{
+The `cir.bswap` operation takes an integer as operand, reverse the bytes in
+the object representation of the operand integer, and returns the result.
+
+The operand integer must be an unsigned integer. Its widths must be either
+16, 32, or 64.
+
+Example:
+
+```mlir
+// %0 = 0x12345678
+%0 = cir.const #cir.int<305419896> : !u32i
+
+// %1 should be 0x78563412
+%1 = cir.bswap(%0 : !u32i) : !u32i
+```
+  }];
+
+  let results = (outs CIR_IntType:$result);
+  let arguments = (ins CIR_UIntOfWidths<[16, 32, 64]>:$input);
+
+  let assemblyFormat = [{
+`(` $input `:` type($input) `)` `:` type($result) attr-dict
+  }];
+}
+
 
//===--===//
 // Assume Operations
 
//===--===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index fb046533a91b8..25be6f35df501 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -60,15 +60,15 @@ static RValue emitBuiltinBitOp(CIRGenFunction &cgf, const 
CallExpr *e,
 RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned 
builtinID,
const CallExpr *e,
ReturnValueSlot returnValue) {
+  mlir::Location loc = getLoc(e->getSourceRange());
+
   // See if we can constant fold this builtin.  If so, don't emit it at all.
   // TODO: Extend this handling to all builtin calls that we can constant-fold.
   Expr::EvalResult result;
   if (e->isPRValue() && e->EvaluateAsRValue(result, cgm.getASTContext()) &&
   !result.hasSideEffects()) {
-if (result.Val.isInt()) {
-  return RValue::get(builder.getConstInt(getLoc(e->getSourceRange()),
- result.Val.getInt()));
-}
+if (result.Val.isInt())
+  return RValue::get(builder.getConstInt(loc, result.Val.getInt()));
 if (result.Val.isFloat()) {
   // Note: we are using result type of CallExpr to determine the type of
   // the constant. Classic codegen uses the result value to determine the
@@ -76,8 +76,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, 
unsigned builtinID,
   // hard to imagine a builtin function evaluates to a value that
   // over/underflows its own defined type.
   mlir::Type type = convertType(e->getType());
-  return RValue::get(builder.getConstFP(getLoc(e->getExprLoc()), type,
-result.Val.getFloat()));
+  return RValue::get(builder.getConstFP(loc, type, result.Val.getFloat()));
 }
   }
 
@@ -101,8 +100,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   assert(!cir::MissingFeatures::builtinCallMathErrno());
   assert(!cir::MissingFeatures::builtinCall());
 
-  mlir::Location loc = getLoc(e->getExprLoc());
-
   switch (builtinIDIfNoAsmLabel) {
   default:
 break;
@@ -185,11 +182,28 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 

[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Sirui Mu via cfe-commits


@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse %0 : !u32i

Lancern wrote:

It looks like we don't have to spell `!u32i` twice since all bit operations are 
`SameOperandsAndResultType`. I'll make a patch to simplify this later.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Sirui Mu via cfe-commits


@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {

Lancern wrote:

Well I think we need to think about what the exact scope of `CIR_BitOpBase` is 
and whether the bit reverse operation should be one of it. I'm naming it 
`bit.reverse` because I think it should follow the `CIR_BitOpBase` convention.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Henrich Lauko via cfe-commits

https://github.com/xlauko edited 
https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Henrich Lauko via cfe-commits


@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {

xlauko wrote:

These are inherited from `CIR_BitOpBase`.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Henrich Lauko via cfe-commits


@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse %0 : !u32i
+```
+  }];
+}
+
+//===--===//
+// ByteswapOp
+//===--===//
+
+def ByteSwapOp : CIR_Op<"bswap", [Pure, SameOperandsAndResultType]> {

xlauko wrote:

```suggestion
def CIR_ByteSwapOp : CIR_Op<"bswap", [Pure, SameOperandsAndResultType]> {
```

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Henrich Lauko via cfe-commits


@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse %0 : !u32i
+```
+  }];
+}
+
+//===--===//
+// ByteswapOp
+//===--===//
+
+def ByteSwapOp : CIR_Op<"bswap", [Pure, SameOperandsAndResultType]> {

xlauko wrote:

This operation has same format results and arguments as `CIR_BitOpBase`. 
It can be used here too.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Henrich Lauko via cfe-commits


@@ -190,6 +190,26 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
 expectedValue, probAttr);
 return RValue::get(result);
   }
+
+  case Builtin::BI__builtin_bswap16:
+  case Builtin::BI__builtin_bswap32:
+  case Builtin::BI__builtin_bswap64:
+  case Builtin::BI_byteswap_ushort:
+  case Builtin::BI_byteswap_ulong:
+  case Builtin::BI_byteswap_uint64: {
+mlir::Value arg = emitScalarExpr(e->getArg(0));
+return RValue::get(
+builder.create(getLoc(e->getSourceRange()), arg));

xlauko wrote:

Lets pull out `mlir::Location loc = getLoc(e->getSourceRange())` to the 
beginning of the function and use it throughout the function. This will reduce 
a lot of unnecessary indent.

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Henrich Lauko via cfe-commits


@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {

xlauko wrote:

I would also suggest to rename to `bitreverse` to mirror builtins name. Also 
dot slightly implies some "namespace".

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Henrich Lauko via cfe-commits


@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {

xlauko wrote:

```suggestion
def CIR_BitReverseOp : CIR_BitOpBase<"bit.reverse", 
  CIR_UIntOfWidths<[8, 16, 32, 64]>
> {
```

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-08 Thread Henrich Lauko via cfe-commits


@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse %0 : !u32i

xlauko wrote:

```suggestion
%1 = cir.bit.reverse( %0 : !u32i) : !u32i
```

https://github.com/llvm/llvm-project/pull/147200
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-06 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clangir

Author: Sirui Mu (Lancern)


Changes

This patch adds support for the following two builtin functions:

- `__builtin_bswap`, represented by the `cir.bswap` operation.
- `__builtin_bitreverse`, represented by the `cir.bit.reverse` operation.

---
Full diff: https://github.com/llvm/llvm-project/pull/147200.diff


5 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+49) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp (+20) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+16) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h (+20) 
- (modified) clang/test/CIR/CodeGen/builtin_bit.cpp (+91) 


``diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 6529f1386599c..e26942d5cf511 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse %0 : !u32i
+```
+  }];
+}
+
+//===--===//
+// ByteswapOp
+//===--===//
+
+def ByteSwapOp : CIR_Op<"bswap", [Pure, SameOperandsAndResultType]> {
+  let summary = "Reverse the bytes in the object representation of the 
operand";
+  let description = [{
+The `cir.bswap` operation takes an integer as operand, reverse the bytes in
+the object representation of the operand integer, and returns the result.
+
+The operand integer must be an unsigned integer. Its widths must be either
+16, 32, or 64.
+
+Example:
+
+```mlir
+// %0 = 0x12345678
+%0 = cir.const #cir.int<305419896> : !u32i
+
+// %1 should be 0x78563412
+%1 = cir.bswap(%0 : !u32i) : !u32i
+```
+  }];
+
+  let results = (outs CIR_IntType:$result);
+  let arguments = (ins CIR_UIntOfWidths<[16, 32, 64]>:$input);
+
+  let assemblyFormat = [{
+`(` $input `:` type($input) `)` `:` type($result) attr-dict
+  }];
+}
+
 
//===--===//
 // Assume Operations
 
//===--===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index fb046533a91b8..6c90bb7975630 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -190,6 +190,26 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
 expectedValue, probAttr);
 return RValue::get(result);
   }
+
+  case Builtin::BI__builtin_bswap16:
+  case Builtin::BI__builtin_bswap32:
+  case Builtin::BI__builtin_bswap64:
+  case Builtin::BI_byteswap_ushort:
+  case Builtin::BI_byteswap_ulong:
+  case Builtin::BI_byteswap_uint64: {
+mlir::Value arg = emitScalarExpr(e->getArg(0));
+return RValue::get(
+builder.create(getLoc(e->getSourceRange()), arg));
+  }
+
+  case Builtin::BI__builtin_bitreverse8:
+  case Builtin::BI__builtin_bitreverse16:
+  case Builtin::BI__builtin_bitreverse32:
+  case Builtin::BI__builtin_bitreverse64: {
+mlir::Value arg = emitScalarExpr(e->getArg(0));
+return RValue::get(
+builder.create(getLoc(e->getSourceRange()), arg));
+  }
   }
 
   cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call");
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 5ac42b6a63b09..acbaae1d227d0 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -535,6 +535,13 @@ mlir::LogicalResult 
CIRToLLVMBitPopcountOpLowering::matchAndRewrite(
   return mlir::LogicalResult::success();
 }
 
+mlir::LogicalResult CIRToLLVMBitReverseOpLowering::matchAndRewrite(
+cir::BitReverseOp op, OpAdaptor adaptor,
+mlir::ConversionPatternRewriter &rewriter) const {
+  rewriter.replaceOpWithNewOp(op, 
adaptor.getInput());
+  return mlir::success();
+}
+
 mlir::LogicalResult CIRToLLVMBrCondOpLowering::matchAndRewrite(
 cir::BrCondOp brOp, OpAdaptor adaptor,
 mlir::ConversionPatternRewriter &rewriter) const {
@@ -551,6 +558,13 @@ mlir::LogicalResult 
CIRToLLVMBrCondOpLowering::matchAndRewrite(
   return mlir::success();
 }
 
+mlir::Logi

[clang] [CIR] Add bit reverse and byte reverse operations (PR #147200)

2025-07-06 Thread Sirui Mu via cfe-commits

https://github.com/Lancern created 
https://github.com/llvm/llvm-project/pull/147200

This patch adds support for the following two builtin functions:

- `__builtin_bswap`, represented by the `cir.bswap` operation.
- `__builtin_bitreverse`, represented by the `cir.bit.reverse` operation.

>From 35ca85872ebc60f36f55c753c6aa33e00d94a91d Mon Sep 17 00:00:00 2001
From: Sirui Mu 
Date: Mon, 7 Jul 2025 00:45:48 +0800
Subject: [PATCH] [CIR] Add bit reverse and byte reverse operations

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 49 ++
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp   | 20 
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 16 
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   | 20 
 clang/test/CIR/CodeGen/builtin_bit.cpp| 91 +++
 5 files changed, 196 insertions(+)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 6529f1386599c..e26942d5cf511 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2661,6 +2661,55 @@ def BitPopcountOp : CIR_BitOpBase<"bit.popcnt",
   }];
 }
 
+def BitReverseOp : CIR_BitOpBase<"bit.reverse", CIR_UIntOfWidths<[8, 16, 32, 
64]>> {
+  let summary = "Reverse the bit pattern of the operand integer";
+  let description = [{
+The `cir.bit.reverse` operation reverses the bits of the operand integer.
+Its only argument must be of unsigned integer types of width 8, 16, 32, or
+64.
+
+This operation covers the C/C++ builtin function `__builtin_bitreverse`.
+
+Example:
+
+```mlir
+%1 = cir.bit.reverse %0 : !u32i
+```
+  }];
+}
+
+//===--===//
+// ByteswapOp
+//===--===//
+
+def ByteSwapOp : CIR_Op<"bswap", [Pure, SameOperandsAndResultType]> {
+  let summary = "Reverse the bytes in the object representation of the 
operand";
+  let description = [{
+The `cir.bswap` operation takes an integer as operand, reverse the bytes in
+the object representation of the operand integer, and returns the result.
+
+The operand integer must be an unsigned integer. Its widths must be either
+16, 32, or 64.
+
+Example:
+
+```mlir
+// %0 = 0x12345678
+%0 = cir.const #cir.int<305419896> : !u32i
+
+// %1 should be 0x78563412
+%1 = cir.bswap(%0 : !u32i) : !u32i
+```
+  }];
+
+  let results = (outs CIR_IntType:$result);
+  let arguments = (ins CIR_UIntOfWidths<[16, 32, 64]>:$input);
+
+  let assemblyFormat = [{
+`(` $input `:` type($input) `)` `:` type($result) attr-dict
+  }];
+}
+
 
//===--===//
 // Assume Operations
 
//===--===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index fb046533a91b8..6c90bb7975630 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -190,6 +190,26 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
 expectedValue, probAttr);
 return RValue::get(result);
   }
+
+  case Builtin::BI__builtin_bswap16:
+  case Builtin::BI__builtin_bswap32:
+  case Builtin::BI__builtin_bswap64:
+  case Builtin::BI_byteswap_ushort:
+  case Builtin::BI_byteswap_ulong:
+  case Builtin::BI_byteswap_uint64: {
+mlir::Value arg = emitScalarExpr(e->getArg(0));
+return RValue::get(
+builder.create(getLoc(e->getSourceRange()), arg));
+  }
+
+  case Builtin::BI__builtin_bitreverse8:
+  case Builtin::BI__builtin_bitreverse16:
+  case Builtin::BI__builtin_bitreverse32:
+  case Builtin::BI__builtin_bitreverse64: {
+mlir::Value arg = emitScalarExpr(e->getArg(0));
+return RValue::get(
+builder.create(getLoc(e->getSourceRange()), arg));
+  }
   }
 
   cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call");
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 5ac42b6a63b09..acbaae1d227d0 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -535,6 +535,13 @@ mlir::LogicalResult 
CIRToLLVMBitPopcountOpLowering::matchAndRewrite(
   return mlir::LogicalResult::success();
 }
 
+mlir::LogicalResult CIRToLLVMBitReverseOpLowering::matchAndRewrite(
+cir::BitReverseOp op, OpAdaptor adaptor,
+mlir::ConversionPatternRewriter &rewriter) const {
+  rewriter.replaceOpWithNewOp(op, 
adaptor.getInput());
+  return mlir::success();
+}
+
 mlir::LogicalResult CIRToLLVMBrCondOpLowering::matchAndRewrite(
 cir::BrCondOp brOp, OpAdaptor adaptor,
 mlir::ConversionPatternRewriter &rewriter) const {
@@ -551,6 +558,13 @@ mlir::LogicalResult 
CIRToLLV