@@ -78,6 +78,156 @@ class LLVMLoweringInfo {
7878class CIR_Op<string mnemonic, list<Trait> traits = []> :
7979 Op<CIR_Dialect, mnemonic, traits>, LLVMLoweringInfo;
8080
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+
81231//===----------------------------------------------------------------------===//
82232// ConstantOp
83233//===----------------------------------------------------------------------===//
0 commit comments