Skip to content

Commit c2adbf1

Browse files
authored
[CIR] Backport ComplexReal/Imag Ops to work on boolean type (#2039)
Backport ComplexReal/Imag Ops to work on the boolean type from the upstream
1 parent cc9ff3a commit c2adbf1

File tree

3 files changed

+67
-13
lines changed

3 files changed

+67
-13
lines changed

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

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,18 +1514,20 @@ def CIR_ComplexCreateOp : CIR_Op<"complex.create", [Pure, SameTypeOperands]> {
15141514
def CIR_ComplexRealOp : CIR_Op<"complex.real", [Pure]> {
15151515
let summary = "Extract the real part of a complex value";
15161516
let description = [{
1517-
`cir.complex.real` operation takes an operand of `!cir.complex` type and
1518-
yields the real part of it.
1517+
`cir.complex.real` operation takes an operand of `!cir.complex`, `cir.int`,
1518+
`!cir.bool` or `!cir.float`. If the operand is `!cir.complex`, the real
1519+
part of it will be returned, otherwise the value returned unmodified.
15191520

15201521
Example:
15211522

15221523
```mlir
1523-
%1 = cir.complex.real %0 : !cir.complex<!cir.float> -> !cir.float
1524+
%real = cir.complex.real %complex : !cir.complex<!cir.float> -> !cir.float
1525+
%real = cir.complex.real %scalar : !cir.float -> !cir.float
15241526
```
15251527
}];
15261528

1527-
let results = (outs CIR_AnyIntOrFloatType:$result);
1528-
let arguments = (ins CIR_AnyComplexOrIntOrFloatType:$operand);
1529+
let results = (outs CIR_AnyIntOrBoolOrFloatType:$result);
1530+
let arguments = (ins CIR_AnyComplexOrIntOrBoolOrFloatType:$operand);
15291531

15301532
let assemblyFormat = [{
15311533
$operand `:` qualified(type($operand)) `->` qualified(type($result))
@@ -1540,8 +1542,8 @@ def CIR_ComplexImagOp : CIR_Op<"complex.imag", [Pure]> {
15401542
let summary = "Extract the imaginary part of a complex value";
15411543
let description = [{
15421544
`cir.complex.imag` operation takes an operand of `!cir.complex`, `!cir.int`
1543-
or `!cir.float`. If the operand is `!cir.complex`, the imag part of it will
1544-
be returned, otherwise a zero value will be returned.
1545+
`!cir.bool` or `!cir.float`. If the operand is `!cir.complex`, the imag
1546+
part of it will be returned, otherwise a zero value will be returned.
15451547

15461548
Example:
15471549

@@ -1551,8 +1553,8 @@ def CIR_ComplexImagOp : CIR_Op<"complex.imag", [Pure]> {
15511553
```
15521554
}];
15531555

1554-
let results = (outs CIR_AnyIntOrFloatType:$result);
1555-
let arguments = (ins CIR_AnyComplexOrIntOrFloatType:$operand);
1556+
let results = (outs CIR_AnyIntOrBoolOrFloatType:$result);
1557+
let arguments = (ins CIR_AnyComplexOrIntOrBoolOrFloatType:$operand);
15561558

15571559
let assemblyFormat = [{
15581560
$operand `:` qualified(type($operand)) `->` qualified(type($result))

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,16 +163,22 @@ def CIR_AnyIntOrFloatType : AnyTypeOf<[CIR_AnyFloatType, CIR_AnyIntType],
163163
let cppFunctionName = "isAnyIntegerOrFloatingPointType";
164164
}
165165

166+
def CIR_AnyIntOrBoolOrFloatType
167+
: AnyTypeOf<[CIR_AnyBoolType, CIR_AnyFloatType, CIR_AnyIntType],
168+
"integer, boolean or floating point type"> {
169+
let cppFunctionName = "isAnyIntegerOrBooleanOrFloatingPointType";
170+
}
171+
166172
//===----------------------------------------------------------------------===//
167173
// Complex Type predicates
168174
//===----------------------------------------------------------------------===//
169175

170176
def CIR_AnyComplexType : CIR_TypeBase<"::cir::ComplexType", "complex type">;
171177

172-
def CIR_AnyComplexOrIntOrFloatType : AnyTypeOf<[
173-
CIR_AnyComplexType, CIR_AnyFloatType, CIR_AnyIntType
174-
], "complex, integer or floating point type"> {
175-
let cppFunctionName = "isComplexOrIntegerOrFloatingPointType";
178+
def CIR_AnyComplexOrIntOrBoolOrFloatType
179+
: AnyTypeOf<[CIR_AnyComplexType, CIR_AnyIntOrBoolOrFloatType],
180+
"complex, integer, bool or floating point type"> {
181+
let cppFunctionName = "isComplexOrIntegerOrBoolOrFloatingPointType";
176182
}
177183

178184
//===----------------------------------------------------------------------===//

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,3 +410,49 @@ void imag_on_scalar_glvalue() {
410410
// OGCG: %[[A_ADDR:.*]] = alloca float, align 4
411411
// OGCG: %[[B_ADDR:.*]] = alloca float, align 4
412412
// OGCG: store float 0.000000e+00, ptr %[[B_ADDR]], align 4
413+
414+
void real_on_scalar_bool() {
415+
bool a;
416+
bool b = __real__ a;
417+
}
418+
419+
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["a"]
420+
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["b", init]
421+
// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.bool>, !cir.bool
422+
// CIR: %[[A_REAL:.*]] = cir.complex.real %[[TMP_A]] : !cir.bool -> !cir.bool
423+
// CIR: cir.store{{.*}} %[[A_REAL]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>
424+
425+
// LLVM: %[[A_ADDR:.*]] = alloca i8, i64 1, align 1
426+
// LLVM: %[[B_ADDR:.*]] = alloca i8, i64 1, align 1
427+
// LLVM: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1
428+
// LLVM: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1
429+
// LLVM: %[[TMP_A_I8:.*]] = zext i1 %[[TMP_A_I1]] to i8
430+
// LLVM: store i8 %[[TMP_A_I8]], ptr %[[B_ADDR]], align 1
431+
432+
// OGCG: %[[A_ADDR:.*]] = alloca i8, align 1
433+
// OGCG: %[[B_ADDR:.*]] = alloca i8, align 1
434+
// OGCG: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1
435+
// OGCG: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1
436+
// OGCG: %[[TMP_A_I8:.*]] = zext i1 %[[TMP_A_I1]] to i8
437+
// OGCG: store i8 %[[TMP_A_I8]], ptr %[[B_ADDR]], align 1
438+
439+
void imag_on_scalar_bool() {
440+
bool a;
441+
bool b = __imag__ a;
442+
}
443+
444+
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["a"]
445+
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["b", init]
446+
// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.bool>, !cir.bool
447+
// CIR: %[[A_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.bool -> !cir.bool
448+
// CIR: cir.store{{.*}} %[[A_IMAG]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>
449+
450+
// LLVM: %[[A_ADDR:.*]] = alloca i8, i64 1, align 1
451+
// LLVM: %[[B_ADDR:.*]] = alloca i8, i64 1, align 1
452+
// LLVM: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1
453+
// LLVM: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1
454+
// LLVM: store i8 0, ptr %[[B_ADDR]], align 1
455+
456+
// OGCG: %[[A_ADDR:.*]] = alloca i8, align 1
457+
// OGCG: %[[B_ADDR:.*]] = alloca i8, align 1
458+
// OGCG: store i8 0, ptr %[[B_ADDR]], align 1

0 commit comments

Comments
 (0)