Skip to content

Commit c6515fe

Browse files
committed
Rename CIR bit operations to cir.bit.*
1 parent 55d84a4 commit c6515fe

File tree

6 files changed

+409
-136
lines changed

6 files changed

+409
-136
lines changed

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

Lines changed: 155 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -993,35 +993,167 @@ def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
993993
// BitsOp
994994
//===----------------------------------------------------------------------===//
995995

996-
def BitsOpKind_CLRSB : I32EnumAttrCase<"clrsb", 1>;
997-
def BitsOpKind_CTZ : I32EnumAttrCase<"ctz", 2>;
998-
def BitsOpKind_CLZ : I32EnumAttrCase<"clz", 3>;
999-
def BitsOpKind_FFS : I32EnumAttrCase<"ffs", 4>;
1000-
def BitsOpKind_PARITY : I32EnumAttrCase<"parity", 5>;
1001-
def BitsOpKind_POPCOUNT : I32EnumAttrCase<"popcount", 6>;
1002-
1003-
def BitsOpKind : I32EnumAttr<
1004-
"BitsOpKind", "bits op kind", [
1005-
BitsOpKind_CLRSB, BitsOpKind_CTZ, BitsOpKind_CLZ, BitsOpKind_FFS,
1006-
BitsOpKind_PARITY, BitsOpKind_POPCOUNT,
1007-
]> {
1008-
let cppNamespace = "::mlir::cir";
996+
class CIR_BitOp<string mnemonic> : CIR_Op<mnemonic, [Pure]> {
997+
let arguments = (ins CIR_IntType:$input);
998+
let results = (outs CIR_IntType:$result);
999+
1000+
let assemblyFormat = [{
1001+
`(` $input `:` type($input) `)` `:` type($result) attr-dict
1002+
}];
10091003
}
10101004

1011-
def BitsOp : CIR_Op<"bits", [Pure]> {
1012-
let summary = "Perform bit operations on the input integer";
1005+
def BitClrsbOp : CIR_BitOp<"bit.clrsb"> {
1006+
let summary = "Get the number of leading redundant sign bits in the input";
10131007
let description = [{
1014-
`cir.bits` performs bit-level operations on the input integral operand.
1015-
All supported operations include `clrsb`, `ctz`, `clz`, `ffs`, `parity`,
1016-
and `popcount`.
1008+
Compute the number of leading redundant sign bits in the input integer.
1009+
1010+
The input integer must be a signed integer. The most significant bit of the
1011+
input integer is the sign bit. The `cir.bit.clrsb` operation returns the
1012+
number of redundant sign bits in the input, that is, the number of bits
1013+
following the most significant bit that are identical to it.
1014+
1015+
Examples:
1016+
1017+
```mlir
1018+
!s32i = !cir.int<s, 32>
1019+
1020+
// %0 = 0xDEADBEEF, 0b1101_1110_1010_1101_1011_1110_1110_1111
1021+
%0 = cir.const(#cir.int<3735928559> : !s32i) : !s32i
1022+
// %1 will be 1 because there is 1 bit following the most significant bit
1023+
// that is identical to it.
1024+
%1 = cir.bit.clrsb(%0 : !s32i) : !s32i
1025+
1026+
// %2 = 1, 0b0000_0000_0000_0000_0000_0000_0000_0001
1027+
%2 = cir.const(#cir.int<1> : !s32i) : !s32i
1028+
// %3 will be 30
1029+
%3 = cir.bit.clrsb(%2 : !s32i) : !s32i
1030+
```
10171031
}];
10181032

1019-
let results = (outs CIR_IntType:$result);
1020-
let arguments = (ins Arg<BitsOpKind, "op kind">:$kind,
1021-
CIR_IntType:$input);
1033+
let hasVerifier = 1;
1034+
}
10221035

1023-
let assemblyFormat = [{
1024-
`(` $kind `,` $input `:` type($input) `)` `:` type($result) attr-dict
1036+
def BitCtzOp : CIR_BitOp<"bit.ctz"> {
1037+
let summary = "Get the number of trailing 0-bits in the input";
1038+
let description = [{
1039+
Compute the number of trailing 0-bits in the input.
1040+
1041+
The input integer must be an unsigned integer. The `cir.bit.ctz` operation
1042+
returns the number of consecutive 0-bits at the least significant bit
1043+
position in the input.
1044+
1045+
This operation invokes undefined behavior if the input value is 0.
1046+
1047+
Example:
1048+
1049+
```mlir
1050+
!s32i = !cir.int<s, 32>
1051+
!u32i = !cir.int<u, 32>
1052+
1053+
// %0 = 0b1000
1054+
%0 = cir.const(#cir.int<8> : !u32i) : !u32i
1055+
// %1 will be 3
1056+
%1 = cir.bit.ctz(%0 : !u32i) : !s32i
1057+
```
1058+
}];
1059+
1060+
let hasVerifier = 1;
1061+
}
1062+
1063+
def BitClzOp : CIR_BitOp<"bit.clz"> {
1064+
let summary = "Get the number of leading 0-bits in the input";
1065+
let description = [{
1066+
Compute the number of leading 0-bits in the input.
1067+
1068+
The input integer must be an unsigned integer. The `cir.bit.clz` operation
1069+
returns the number of consecutive 0-bits at the most significant bit
1070+
position in the input.
1071+
1072+
This operation invokes undefined behavior if the input value is 0.
1073+
1074+
Example:
1075+
1076+
```mlir
1077+
!s32i = !cir.int<s, 32>
1078+
!u32i = !cir.int<u, 32>
1079+
1080+
// %0 = 0b0000_0000_0000_0000_0000_0000_0000_1000
1081+
%0 = cir.const(#cir.int<8> : !u32i) : !u32i
1082+
// %1 will be 28
1083+
%1 = cir.bit.clz(%0 : !u32i) : !s32i
1084+
```
1085+
}];
1086+
1087+
let hasVerifier = 1;
1088+
}
1089+
1090+
def BitFfsOp : CIR_BitOp<"bit.ffs"> {
1091+
let summary = "Get the position of the least significant 1-bit of input";
1092+
let description = [{
1093+
Compute the position of the least significant 1-bit of the input.
1094+
1095+
The input integer must be a signed integer. The `cir.bit.ffs` operation
1096+
returns one plus the index of the least significant 1-bit of the input
1097+
signed integer. As a special case, if the input integer is 0, `cir.bit.ffs`
1098+
returns 0.
1099+
1100+
Example:
1101+
1102+
```mlir
1103+
!s32i = !cir.int<s, 32>
1104+
1105+
// %0 = 0x0010_1000
1106+
%0 = cir.const(#cir.int<40> : !s32i) : !s32i
1107+
// #1 will be 4 since the 4th least significant bit is 1.
1108+
%1 = cir.bit.ffs(%0 : !s32i) : !s32i
1109+
```
1110+
}];
1111+
1112+
let hasVerifier = 1;
1113+
}
1114+
1115+
def BitParityOp : CIR_BitOp<"bit.parity"> {
1116+
let summary = "Get the parity of input";
1117+
let description = [{
1118+
Compute the parity of the input. The parity of an integer is the number of
1119+
1-bits in it modulo 2.
1120+
1121+
The input must be an unsigned integer.
1122+
1123+
Example:
1124+
1125+
```mlir
1126+
!s32i = !cir.int<s, 32>
1127+
!u32i = !cir.int<u, 32>
1128+
1129+
// %0 = 0x0110_1000
1130+
%0 = cir.const(#cir.int<104> : !u32i) : !s32i
1131+
// %1 will be 1 since there are 3 1-bits in %0
1132+
%1 = cir.bit.parity(%0 : !u32i) : !s32i
1133+
```
1134+
}];
1135+
1136+
let hasVerifier = 1;
1137+
}
1138+
1139+
def BitPopcountOp : CIR_BitOp<"bit.popcount"> {
1140+
let summary = "Get the number of 1-bits in input";
1141+
let description = [{
1142+
Compute the number of 1-bits in the input.
1143+
1144+
The input must be an unsigned integer.
1145+
1146+
Example:
1147+
1148+
```mlir
1149+
!s32i = !cir.int<s, 32>
1150+
!u32i = !cir.int<u, 32>
1151+
1152+
// %0 = 0x0110_1000
1153+
%0 = cir.const(#cir.int<104> : !u32i) : !s32i
1154+
// %1 will be 3 since there are 3 1-bits in %0
1155+
%1 = cir.bit.popcount(%0 : !u32i) : !s32i
1156+
```
10251157
}];
10261158

10271159
let hasVerifier = 1;

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,19 @@ static RValue buildUnaryFPBuiltin(CIRGenFunction &CGF, const CallExpr &E) {
5555
return RValue::get(Call->getResult(0));
5656
}
5757

58+
template <typename Op>
5859
static RValue
59-
buildBuiltinBitsOp(CIRGenFunction &CGF, const CallExpr *E,
60-
mlir::cir::BitsOpKind Kind,
61-
std::optional<CIRGenFunction::BuiltinCheckKind> CK) {
60+
buildBuiltinBitOp(CIRGenFunction &CGF, const CallExpr *E,
61+
std::optional<CIRGenFunction::BuiltinCheckKind> CK) {
6262
mlir::Value arg;
6363
if (CK.has_value())
6464
arg = CGF.buildCheckedArgForBuiltin(E->getArg(0), *CK);
6565
else
6666
arg = CGF.buildScalarExpr(E->getArg(0));
6767

6868
auto resultTy = CGF.ConvertType(E->getType());
69-
auto op = CGF.getBuilder().create<mlir::cir::BitsOp>(
70-
CGF.getLoc(E->getExprLoc()), resultTy, Kind, arg);
69+
auto op =
70+
CGF.getBuilder().create<Op>(CGF.getLoc(E->getExprLoc()), resultTy, arg);
7171
return RValue::get(op);
7272
}
7373

@@ -499,43 +499,37 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
499499
case Builtin::BI__builtin_clrsb:
500500
case Builtin::BI__builtin_clrsbl:
501501
case Builtin::BI__builtin_clrsbll:
502-
return buildBuiltinBitsOp(*this, E, mlir::cir::BitsOpKind::clrsb,
503-
std::nullopt);
502+
return buildBuiltinBitOp<mlir::cir::BitClrsbOp>(*this, E, std::nullopt);
504503

505504
case Builtin::BI__builtin_ctzs:
506505
case Builtin::BI__builtin_ctz:
507506
case Builtin::BI__builtin_ctzl:
508507
case Builtin::BI__builtin_ctzll:
509-
return buildBuiltinBitsOp(*this, E, mlir::cir::BitsOpKind::ctz,
510-
BCK_CTZPassedZero);
508+
return buildBuiltinBitOp<mlir::cir::BitCtzOp>(*this, E, BCK_CTZPassedZero);
511509

512510
case Builtin::BI__builtin_clzs:
513511
case Builtin::BI__builtin_clz:
514512
case Builtin::BI__builtin_clzl:
515513
case Builtin::BI__builtin_clzll:
516-
return buildBuiltinBitsOp(*this, E, mlir::cir::BitsOpKind::clz,
517-
BCK_CLZPassedZero);
514+
return buildBuiltinBitOp<mlir::cir::BitClzOp>(*this, E, BCK_CLZPassedZero);
518515

519516
case Builtin::BI__builtin_ffs:
520517
case Builtin::BI__builtin_ffsl:
521518
case Builtin::BI__builtin_ffsll:
522-
return buildBuiltinBitsOp(*this, E, mlir::cir::BitsOpKind::ffs,
523-
std::nullopt);
519+
return buildBuiltinBitOp<mlir::cir::BitFfsOp>(*this, E, std::nullopt);
524520

525521
case Builtin::BI__builtin_parity:
526522
case Builtin::BI__builtin_parityl:
527523
case Builtin::BI__builtin_parityll:
528-
return buildBuiltinBitsOp(*this, E, mlir::cir::BitsOpKind::parity,
529-
std::nullopt);
524+
return buildBuiltinBitOp<mlir::cir::BitParityOp>(*this, E, std::nullopt);
530525

531526
case Builtin::BI__popcnt16:
532527
case Builtin::BI__popcnt:
533528
case Builtin::BI__popcnt64:
534529
case Builtin::BI__builtin_popcount:
535530
case Builtin::BI__builtin_popcountl:
536531
case Builtin::BI__builtin_popcountll:
537-
return buildBuiltinBitsOp(*this, E, mlir::cir::BitsOpKind::popcount,
538-
std::nullopt);
532+
return buildBuiltinBitOp<mlir::cir::BitPopcountOp>(*this, E, std::nullopt);
539533
}
540534

541535
// If this is an alias for a lib function (e.g. __builtin_sin), emit

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -844,61 +844,57 @@ Block *BrCondOp::getSuccessorForOperands(ArrayRef<Attribute> operands) {
844844
}
845845

846846
//===----------------------------------------------------------------------===//
847-
// BitsOp
847+
// CIR_BitOp family of operations
848848
//===----------------------------------------------------------------------===//
849849

850-
LogicalResult BitsOp::verify() {
851-
auto inputTy = getInput().getType();
852-
auto inputIsSigned = inputTy.getIsSigned();
853-
auto inputWidth = inputTy.getWidth();
854-
855-
switch (getKind()) {
856-
case mlir::cir::BitsOpKind::clrsb:
857-
case mlir::cir::BitsOpKind::ffs:
858-
// Input to clrsb and ffs must be signed integer of width 32 and 64.
859-
if (!inputIsSigned) {
860-
return emitOpError(
861-
"input value to clrsb or ffs must be a signed integer");
862-
}
863-
if (inputWidth != 32 && inputWidth != 64) {
864-
return emitOpError(
865-
"input value to clrsb or ffs must be a 32-bit or 64-bit integer");
866-
}
867-
break;
850+
LogicalResult BitClrsbOp::verify() {
851+
if (!getInput().getType().isSigned())
852+
return emitOpError("input of cir.bit.clrsb must be a signed integer");
853+
if (!getType().isSigned() || getType().getWidth() != 32)
854+
return emitOpError(
855+
"result of cir.bit.clrsb must be a 32-bit signed integer");
856+
return success();
857+
}
868858

869-
case mlir::cir::BitsOpKind::clz:
870-
case mlir::cir::BitsOpKind::ctz:
871-
case mlir::cir::BitsOpKind::popcount:
872-
if (inputIsSigned) {
873-
return emitOpError("input value to clz, ctz, parity, or popcount must be "
874-
"an unsigned integer");
875-
}
876-
if (inputWidth != 16 && inputWidth != 32 && inputWidth != 64) {
877-
return emitOpError("input value to clz, ctz, parity, or popcount must be "
878-
"either a 16-bit, a 32-bit, or a 64-bit integer");
879-
}
880-
break;
859+
LogicalResult BitClzOp::verify() {
860+
if (!getInput().getType().isUnsigned())
861+
return emitOpError("input of cir.bit.clz must be an unsigned integer");
862+
if (!getType().isSigned() || getType().getWidth() != 32)
863+
return emitOpError("result of cir.bit.clz must be a 32-bit signed integer");
864+
return success();
865+
}
881866

882-
case mlir::cir::BitsOpKind::parity:
883-
if (inputIsSigned) {
884-
return emitOpError("input value to parity must be an unsigned integer");
885-
}
886-
if (inputWidth != 32 && inputWidth != 64) {
887-
return emitOpError(
888-
"input value to parity must be a 32-bit or 64-bit integer");
889-
}
890-
break;
867+
LogicalResult BitCtzOp::verify() {
868+
if (!getInput().getType().isUnsigned())
869+
return emitOpError("input of cir.bit.ctz must be an unsigned integer");
870+
if (!getType().isSigned() || getType().getWidth() != 32)
871+
return emitOpError("result of cir.bit.ctz must be a 32-bit signed integer");
872+
return success();
873+
}
891874

892-
default:
893-
llvm_unreachable("unknown bits operation kind");
894-
}
875+
LogicalResult BitFfsOp::verify() {
876+
if (!getInput().getType().isSigned())
877+
return emitOpError("input of cir.bit.ffs must be a signed integer");
878+
if (!getType().isSigned() || getType().getWidth() != 32)
879+
return emitOpError("result of cir.bit.ffs must be a 32-bit signed integer");
880+
return success();
881+
}
895882

896-
auto resultTy = getType();
897-
// TODO: how should we deal with targets whose `int` is not `int32_t`?
898-
if (!resultTy.getIsSigned() || resultTy.getWidth() != 32) {
899-
return emitOpError("result of cir.bits must be a 32-bit signed integer");
900-
}
883+
LogicalResult BitParityOp::verify() {
884+
if (!getInput().getType().isUnsigned())
885+
return emitOpError("input of cir.bit.parity must be an unsigned integer");
886+
if (!getType().isSigned() || getType().getWidth() != 32)
887+
return emitOpError(
888+
"result of cir.bit.parity must be a 32-bit signed integer");
889+
return success();
890+
}
901891

892+
LogicalResult BitPopcountOp::verify() {
893+
if (!getInput().getType().isUnsigned())
894+
return emitOpError("input of cir.bit.popcount must be an unsigned integer");
895+
if (!getType().isSigned() || getType().getWidth() != 32)
896+
return emitOpError(
897+
"result of cir.bit.popcount must be a 32-bit signed integer");
902898
return success();
903899
}
904900

0 commit comments

Comments
 (0)