@@ -993,35 +993,167 @@ def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
993
993
// BitsOp
994
994
//===----------------------------------------------------------------------===//
995
995
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
+ }];
1009
1003
}
1010
1004
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";
1013
1007
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
+ ```
1017
1031
}];
1018
1032
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
+ }
1022
1035
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
+ ```
1025
1157
}];
1026
1158
1027
1159
let hasVerifier = 1;
0 commit comments