Skip to content

Commit 5821446

Browse files
authored
[CIR] Update ComplexReal/Imag Ops to work on boolean type (#161956)
Update ComplexRealOp and ComplexImagOp to work on the boolean type. Issue #160568
1 parent ddef9ad commit 5821446

File tree

3 files changed

+65
-13
lines changed

3 files changed

+65
-13
lines changed

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3277,9 +3277,9 @@ def CIR_ComplexCreateOp : CIR_Op<"complex.create", [Pure, SameTypeOperands]> {
32773277
def CIR_ComplexRealOp : CIR_Op<"complex.real", [Pure]> {
32783278
let summary = "Extract the real part of a complex value";
32793279
let description = [{
3280-
`cir.complex.real` operation takes an operand of `!cir.complex`, `!cir.int`
3281-
or `!cir.float`. If the operand is `!cir.complex`, the real part of it will
3282-
be returned, otherwise the value returned unmodified.
3280+
`cir.complex.real` operation takes an operand of `!cir.complex`, `cir.int`,
3281+
`!cir.bool` or `!cir.float`. If the operand is `!cir.complex`, the real
3282+
part of it will be returned, otherwise the value returned unmodified.
32833283

32843284
Example:
32853285

@@ -3289,8 +3289,8 @@ def CIR_ComplexRealOp : CIR_Op<"complex.real", [Pure]> {
32893289
```
32903290
}];
32913291

3292-
let results = (outs CIR_AnyIntOrFloatType:$result);
3293-
let arguments = (ins CIR_AnyComplexOrIntOrFloatType:$operand);
3292+
let results = (outs CIR_AnyIntOrBoolOrFloatType:$result);
3293+
let arguments = (ins CIR_AnyComplexOrIntOrBoolOrFloatType:$operand);
32943294

32953295
let assemblyFormat = [{
32963296
$operand `:` qualified(type($operand)) `->` qualified(type($result))
@@ -3309,8 +3309,8 @@ def CIR_ComplexImagOp : CIR_Op<"complex.imag", [Pure]> {
33093309
let summary = "Extract the imaginary part of a complex value";
33103310
let description = [{
33113311
`cir.complex.imag` operation takes an operand of `!cir.complex`, `!cir.int`
3312-
or `!cir.float`. If the operand is `!cir.complex`, the imag part of it will
3313-
be returned, otherwise a zero value will be returned.
3312+
`!cir.bool` or `!cir.float`. If the operand is `!cir.complex`, the imag
3313+
part of it will be returned, otherwise a zero value will be returned.
33143314

33153315
Example:
33163316

@@ -3320,8 +3320,8 @@ def CIR_ComplexImagOp : CIR_Op<"complex.imag", [Pure]> {
33203320
```
33213321
}];
33223322

3323-
let results = (outs CIR_AnyIntOrFloatType:$result);
3324-
let arguments = (ins CIR_AnyComplexOrIntOrFloatType:$operand);
3323+
let results = (outs CIR_AnyIntOrBoolOrFloatType:$result);
3324+
let arguments = (ins CIR_AnyComplexOrIntOrBoolOrFloatType:$operand);
33253325

33263326
let assemblyFormat = [{
33273327
$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
@@ -159,16 +159,22 @@ def CIR_AnyIntOrFloatType : AnyTypeOf<[CIR_AnyFloatType, CIR_AnyIntType],
159159
let cppFunctionName = "isAnyIntegerOrFloatingPointType";
160160
}
161161

162+
def CIR_AnyIntOrBoolOrFloatType
163+
: AnyTypeOf<[CIR_AnyBoolType, CIR_AnyFloatType, CIR_AnyIntType],
164+
"integer, boolean or floating point type"> {
165+
let cppFunctionName = "isAnyIntegerOrBooleanOrFloatingPointType";
166+
}
167+
162168
//===----------------------------------------------------------------------===//
163169
// Complex Type predicates
164170
//===----------------------------------------------------------------------===//
165171

166172
def CIR_AnyComplexType : CIR_TypeBase<"::cir::ComplexType", "complex type">;
167173

168-
def CIR_AnyComplexOrIntOrFloatType : AnyTypeOf<[
169-
CIR_AnyComplexType, CIR_AnyFloatType, CIR_AnyIntType
170-
], "complex, integer or floating point type"> {
171-
let cppFunctionName = "isComplexOrIntegerOrFloatingPointType";
174+
def CIR_AnyComplexOrIntOrBoolOrFloatType
175+
: AnyTypeOf<[CIR_AnyComplexType, CIR_AnyIntOrBoolOrFloatType],
176+
"complex, integer or floating point type"> {
177+
let cppFunctionName = "isComplexOrIntegerOrBoolOrFloatingPointType";
172178
}
173179

174180
//===----------------------------------------------------------------------===//

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,3 +1359,49 @@ void complex_type_argument() {
13591359
// OGCG: store float %[[A_IMAG]], ptr %[[ARG_IMAG_PTR]], align 4
13601360
// OGCG: %[[TMP_ARG:.*]] = load <2 x float>, ptr %[[ARG_ADDR]], align 4
13611361
// OGCG: call void @_Z22complex_type_parameterCf(<2 x float> noundef %[[TMP_ARG]])
1362+
1363+
void real_on_scalar_bool() {
1364+
bool a;
1365+
bool b = __real__ a;
1366+
}
1367+
1368+
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["a"]
1369+
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["b", init]
1370+
// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.bool>, !cir.bool
1371+
// CIR: %[[A_REAL:.*]] = cir.complex.real %[[TMP_A]] : !cir.bool -> !cir.bool
1372+
// CIR: cir.store{{.*}} %[[A_REAL]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>
1373+
1374+
// LLVM: %[[A_ADDR:.*]] = alloca i8, i64 1, align 1
1375+
// LLVM: %[[B_ADDR:.*]] = alloca i8, i64 1, align 1
1376+
// LLVM: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1
1377+
// LLVM: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1
1378+
// LLVM: %[[TMP_A_I8:.*]] = zext i1 %[[TMP_A_I1]] to i8
1379+
// LLVM: store i8 %[[TMP_A_I8]], ptr %[[B_ADDR]], align 1
1380+
1381+
// OGCG: %[[A_ADDR:.*]] = alloca i8, align 1
1382+
// OGCG: %[[B_ADDR:.*]] = alloca i8, align 1
1383+
// OGCG: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1
1384+
// OGCG: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1
1385+
// OGCG: %[[TMP_A_I8:.*]] = zext i1 %[[TMP_A_I1]] to i8
1386+
// OGCG: store i8 %[[TMP_A_I8]], ptr %[[B_ADDR]], align 1
1387+
1388+
void imag_on_scalar_bool() {
1389+
bool a;
1390+
bool b = __imag__ a;
1391+
}
1392+
1393+
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["a"]
1394+
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["b", init]
1395+
// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.bool>, !cir.bool
1396+
// CIR: %[[A_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.bool -> !cir.bool
1397+
// CIR: cir.store{{.*}} %[[A_IMAG]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>
1398+
1399+
// LLVM: %[[A_ADDR:.*]] = alloca i8, i64 1, align 1
1400+
// LLVM: %[[B_ADDR:.*]] = alloca i8, i64 1, align 1
1401+
// LLVM: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1
1402+
// LLVM: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1
1403+
// LLVM: store i8 0, ptr %[[B_ADDR]], align 1
1404+
1405+
// OGCG: %[[A_ADDR:.*]] = alloca i8, align 1
1406+
// OGCG: %[[B_ADDR:.*]] = alloca i8, align 1
1407+
// OGCG: store i8 0, ptr %[[B_ADDR]], align 1

0 commit comments

Comments
 (0)