diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index c81f64deff7bc..b8e541d7618ec 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -3277,9 +3277,9 @@ def CIR_ComplexCreateOp : CIR_Op<"complex.create", [Pure, SameTypeOperands]> { def CIR_ComplexRealOp : CIR_Op<"complex.real", [Pure]> { let summary = "Extract the real part of a complex value"; let description = [{ - `cir.complex.real` operation takes an operand of `!cir.complex`, `!cir.int` - or `!cir.float`. If the operand is `!cir.complex`, the real part of it will - be returned, otherwise the value returned unmodified. + `cir.complex.real` operation takes an operand of `!cir.complex`, `cir.int`, + `!cir.bool` or `!cir.float`. If the operand is `!cir.complex`, the real + part of it will be returned, otherwise the value returned unmodified. Example: @@ -3289,8 +3289,8 @@ def CIR_ComplexRealOp : CIR_Op<"complex.real", [Pure]> { ``` }]; - let results = (outs CIR_AnyIntOrFloatType:$result); - let arguments = (ins CIR_AnyComplexOrIntOrFloatType:$operand); + let results = (outs CIR_AnyIntOrBoolOrFloatType:$result); + let arguments = (ins CIR_AnyComplexOrIntOrBoolOrFloatType:$operand); let assemblyFormat = [{ $operand `:` qualified(type($operand)) `->` qualified(type($result)) @@ -3309,8 +3309,8 @@ def CIR_ComplexImagOp : CIR_Op<"complex.imag", [Pure]> { let summary = "Extract the imaginary part of a complex value"; let description = [{ `cir.complex.imag` operation takes an operand of `!cir.complex`, `!cir.int` - or `!cir.float`. If the operand is `!cir.complex`, the imag part of it will - be returned, otherwise a zero value will be returned. + `!cir.bool` or `!cir.float`. If the operand is `!cir.complex`, the imag + part of it will be returned, otherwise a zero value will be returned. Example: @@ -3320,8 +3320,8 @@ def CIR_ComplexImagOp : CIR_Op<"complex.imag", [Pure]> { ``` }]; - let results = (outs CIR_AnyIntOrFloatType:$result); - let arguments = (ins CIR_AnyComplexOrIntOrFloatType:$operand); + let results = (outs CIR_AnyIntOrBoolOrFloatType:$result); + let arguments = (ins CIR_AnyComplexOrIntOrBoolOrFloatType:$operand); let assemblyFormat = [{ $operand `:` qualified(type($operand)) `->` qualified(type($result)) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td index da03a291a7690..a1ebd6cccc0b8 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -159,16 +159,22 @@ def CIR_AnyIntOrFloatType : AnyTypeOf<[CIR_AnyFloatType, CIR_AnyIntType], let cppFunctionName = "isAnyIntegerOrFloatingPointType"; } +def CIR_AnyIntOrBoolOrFloatType + : AnyTypeOf<[CIR_AnyBoolType, CIR_AnyFloatType, CIR_AnyIntType], + "integer, boolean or floating point type"> { + let cppFunctionName = "isAnyIntegerOrBooleanOrFloatingPointType"; +} + //===----------------------------------------------------------------------===// // Complex Type predicates //===----------------------------------------------------------------------===// def CIR_AnyComplexType : CIR_TypeBase<"::cir::ComplexType", "complex type">; -def CIR_AnyComplexOrIntOrFloatType : AnyTypeOf<[ - CIR_AnyComplexType, CIR_AnyFloatType, CIR_AnyIntType -], "complex, integer or floating point type"> { - let cppFunctionName = "isComplexOrIntegerOrFloatingPointType"; +def CIR_AnyComplexOrIntOrBoolOrFloatType + : AnyTypeOf<[CIR_AnyComplexType, CIR_AnyIntOrBoolOrFloatType], + "complex, integer or floating point type"> { + let cppFunctionName = "isComplexOrIntegerOrBoolOrFloatingPointType"; } //===----------------------------------------------------------------------===// diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index 3524b8bb07ad1..537fb8ae902a8 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -1359,3 +1359,49 @@ void complex_type_argument() { // OGCG: store float %[[A_IMAG]], ptr %[[ARG_IMAG_PTR]], align 4 // OGCG: %[[TMP_ARG:.*]] = load <2 x float>, ptr %[[ARG_ADDR]], align 4 // OGCG: call void @_Z22complex_type_parameterCf(<2 x float> noundef %[[TMP_ARG]]) + +void real_on_scalar_bool() { + bool a; + bool b = __real__ a; +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr, ["a"] +// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr, ["b", init] +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr, !cir.bool +// CIR: %[[A_REAL:.*]] = cir.complex.real %[[TMP_A]] : !cir.bool -> !cir.bool +// CIR: cir.store{{.*}} %[[A_REAL]], %[[B_ADDR]] : !cir.bool, !cir.ptr + +// LLVM: %[[A_ADDR:.*]] = alloca i8, i64 1, align 1 +// LLVM: %[[B_ADDR:.*]] = alloca i8, i64 1, align 1 +// LLVM: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1 +// LLVM: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1 +// LLVM: %[[TMP_A_I8:.*]] = zext i1 %[[TMP_A_I1]] to i8 +// LLVM: store i8 %[[TMP_A_I8]], ptr %[[B_ADDR]], align 1 + +// OGCG: %[[A_ADDR:.*]] = alloca i8, align 1 +// OGCG: %[[B_ADDR:.*]] = alloca i8, align 1 +// OGCG: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1 +// OGCG: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1 +// OGCG: %[[TMP_A_I8:.*]] = zext i1 %[[TMP_A_I1]] to i8 +// OGCG: store i8 %[[TMP_A_I8]], ptr %[[B_ADDR]], align 1 + +void imag_on_scalar_bool() { + bool a; + bool b = __imag__ a; +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr, ["a"] +// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr, ["b", init] +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr, !cir.bool +// CIR: %[[A_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.bool -> !cir.bool +// CIR: cir.store{{.*}} %[[A_IMAG]], %[[B_ADDR]] : !cir.bool, !cir.ptr + +// LLVM: %[[A_ADDR:.*]] = alloca i8, i64 1, align 1 +// LLVM: %[[B_ADDR:.*]] = alloca i8, i64 1, align 1 +// LLVM: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1 +// LLVM: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1 +// LLVM: store i8 0, ptr %[[B_ADDR]], align 1 + +// OGCG: %[[A_ADDR:.*]] = alloca i8, align 1 +// OGCG: %[[B_ADDR:.*]] = alloca i8, align 1 +// OGCG: store i8 0, ptr %[[B_ADDR]], align 1