@@ -78,6 +78,156 @@ class LLVMLoweringInfo {
78
78
class CIR_Op<string mnemonic, list<Trait> traits = []> :
79
79
Op<CIR_Dialect, mnemonic, traits>, LLVMLoweringInfo;
80
80
81
+ //===----------------------------------------------------------------------===//
82
+ // CastOp
83
+ //===----------------------------------------------------------------------===//
84
+
85
+ // CK_Dependent
86
+ def CK_BitCast : I32EnumAttrCase<"bitcast", 1>;
87
+ // CK_LValueBitCast
88
+ // CK_LValueToRValueBitCast
89
+ // CK_LValueToRValue
90
+ // CK_NoOp
91
+ // CK_BaseToDerived
92
+ // CK_DerivedToBase
93
+ // CK_UncheckedDerivedToBase
94
+ // CK_Dynamic
95
+ // CK_ToUnion
96
+ def CK_ArrayToPointerDecay : I32EnumAttrCase<"array_to_ptrdecay", 11>;
97
+ // CK_FunctionToPointerDecay
98
+ // CK_NullToPointer
99
+ // CK_NullToMemberPointer
100
+ // CK_BaseToDerivedMemberPointer
101
+ // CK_DerivedToBaseMemberPointer
102
+ def CK_MemberPointerToBoolean : I32EnumAttrCase<"member_ptr_to_bool", 17>;
103
+ // CK_ReinterpretMemberPointer
104
+ // CK_UserDefinedConversion
105
+ // CK_ConstructorConversion
106
+ def CK_IntegralToPointer : I32EnumAttrCase<"int_to_ptr", 21>;
107
+ def CK_PointerToIntegral : I32EnumAttrCase<"ptr_to_int", 22>;
108
+ def CK_PointerToBoolean : I32EnumAttrCase<"ptr_to_bool", 23>;
109
+ // CK_ToVoid
110
+ // CK_MatrixCast
111
+ // CK_VectorSplat
112
+ def CK_IntegralCast : I32EnumAttrCase<"integral", 27>;
113
+ def CK_IntegralToBoolean : I32EnumAttrCase<"int_to_bool", 28>;
114
+ def CK_IntegralToFloating : I32EnumAttrCase<"int_to_float", 29>;
115
+ // CK_FloatingToFixedPoint
116
+ // CK_FixedPointToFloating
117
+ // CK_FixedPointCast
118
+ // CK_FixedPointToIntegral
119
+ // CK_IntegralToFixedPoint
120
+ // CK_FixedPointToBoolean
121
+ def CK_FloatingToIntegral : I32EnumAttrCase<"float_to_int", 36>;
122
+ def CK_FloatingToBoolean : I32EnumAttrCase<"float_to_bool", 37>;
123
+ def CK_BooleanToSignedIntegral : I32EnumAttrCase<"bool_to_int", 38>;
124
+ def CK_FloatingCast : I32EnumAttrCase<"floating", 39>;
125
+ // CK_CPointerToObjCPointerCast
126
+ // CK_BlockPointerToObjCPointerCast
127
+ // CK_AnyPointerToBlockPointerCast
128
+ // CK_ObjCObjectLValueCast
129
+ // CK_FloatingRealToComplex
130
+ // CK_FloatingComplexToReal
131
+ // CK_FloatingComplexToBoolean
132
+ def CK_FloatingComplexCast : I32EnumAttrCase<"float_complex", 47>;
133
+ // CK_FloatingComplexToIntegralComplex
134
+ // CK_IntegralRealToComplex
135
+ def CK_IntegralComplexToReal : I32EnumAttrCase<"int_complex_to_real", 50>;
136
+ def CK_IntegralComplexToBoolean : I32EnumAttrCase<"int_complex_to_bool", 51>;
137
+ def CK_IntegralComplexCast : I32EnumAttrCase<"int_complex", 52>;
138
+ def CK_IntegralComplexToFloatingComplex
139
+ : I32EnumAttrCase<"int_complex_to_float_complex", 53>;
140
+ // CK_ARCProduceObject
141
+ // CK_ARCConsumeObject
142
+ // CK_ARCReclaimReturnedObject
143
+ // CK_ARCExtendBlockObject
144
+ // CK_AtomicToNonAtomic
145
+ // CK_NonAtomicToAtomic
146
+ // CK_CopyAndAutoreleaseBlockObject
147
+ // CK_BuiltinFnToFnPtr
148
+ // CK_ZeroToOCLOpaqueType
149
+ def CK_AddressSpaceConversion : I32EnumAttrCase<"address_space", 63>;
150
+ // CK_IntToOCLSampler
151
+ // CK_HLSLVectorTruncation
152
+ // CK_HLSLArrayRValue
153
+ // CK_HLSLElementwiseCast
154
+ // CK_HLSLAggregateSplatCast
155
+
156
+ // Enums below are specific to CIR and don't have a correspondence to classic
157
+ // codegen:
158
+ def CK_BooleanToFloat : I32EnumAttrCase<"bool_to_float", 1000>;
159
+
160
+ def CastKind : I32EnumAttr<
161
+ "CastKind",
162
+ "cast kind",
163
+ [CK_BitCast, CK_ArrayToPointerDecay, CK_MemberPointerToBoolean,
164
+ CK_IntegralToPointer, CK_PointerToIntegral, CK_PointerToBoolean,
165
+ CK_IntegralCast, CK_IntegralToBoolean, CK_IntegralToFloating,
166
+ CK_FloatingToIntegral, CK_FloatingToBoolean, CK_BooleanToSignedIntegral,
167
+ CK_FloatingCast, CK_FloatingComplexCast, CK_IntegralComplexToReal,
168
+ CK_IntegralComplexToBoolean, CK_IntegralComplexCast,
169
+ CK_IntegralComplexToFloatingComplex, CK_AddressSpaceConversion,
170
+ CK_BooleanToFloat]> {
171
+ let cppNamespace = "::cir";
172
+ }
173
+
174
+ def CastOp : CIR_Op<"cast",
175
+ [Pure,
176
+ DeclareOpInterfaceMethods<PromotableOpInterface>]> {
177
+ // FIXME: not all conversions are free of side effects.
178
+ let summary = "Conversion between values of different types";
179
+ let description = [{
180
+ Apply C/C++ usual conversions rules between values. Currently supported kinds:
181
+
182
+ - `array_to_ptrdecay`
183
+ - `bitcast`
184
+ - `integral`
185
+ - `int_to_bool`
186
+ - `int_to_float`
187
+ - `floating`
188
+ - `float_to_int`
189
+ - `float_to_bool`
190
+ - `ptr_to_int`
191
+ - `ptr_to_bool`
192
+ - `bool_to_int`
193
+ - `bool_to_float`
194
+ - `address_space`
195
+ - `float_to_complex`
196
+ - `int_to_complex`
197
+ - `float_complex_to_real`
198
+ - `int_complex_to_real`
199
+ - `float_complex_to_bool`
200
+ - `int_complex_to_bool`
201
+ - `float_complex`
202
+ - `float_complex_to_int_complex`
203
+ - `int_complex`
204
+ - `int_complex_to_float_complex`
205
+
206
+ This is effectively a subset of the rules from
207
+ `llvm-project/clang/include/clang/AST/OperationKinds.def`; but note that some
208
+ of the conversions aren't implemented in terms of `cir.cast`, `lvalue-to-rvalue`
209
+ for instance is modeled as a regular `cir.load`.
210
+
211
+ ```mlir
212
+ %4 = cir.cast (int_to_bool, %3 : i32), !cir.bool
213
+ ...
214
+ %x = cir.cast(array_to_ptrdecay, %0 : !cir.ptr<!cir.array<i32 x 10>>), !cir.ptr<i32>
215
+ ```
216
+ }];
217
+
218
+ let arguments = (ins CastKind:$kind, CIR_AnyType:$src);
219
+ let results = (outs CIR_AnyType:$result);
220
+
221
+ let assemblyFormat = [{
222
+ `(` $kind `,` $src `:` type($src) `)`
223
+ `,` type($result) attr-dict
224
+ }];
225
+
226
+ // The input and output types should match the cast kind.
227
+ let hasVerifier = 1;
228
+ let hasFolder = 1;
229
+ }
230
+
81
231
//===----------------------------------------------------------------------===//
82
232
// ConstantOp
83
233
//===----------------------------------------------------------------------===//
0 commit comments