Skip to content

Commit dfc3c25

Browse files
committed
[CIR] __real__ operator on complex rvalue
1 parent 34c12ae commit dfc3c25

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

clang/lib/CIR/CodeGen/CIRGenCall.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -723,8 +723,10 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &CallInfo,
723723

724724
return RValue::get(Results[0]);
725725
}
726-
default:
727-
llvm_unreachable("NYI");
726+
case cir::TEK_Complex: {
727+
mlir::ResultRange results = theCall->getOpResults();
728+
return RValue::getComplex(results[0]);
729+
}
728730
}
729731
}();
730732

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,16 +2054,18 @@ mlir::Value ScalarExprEmitter::VisitReal(const UnaryOperator *E) {
20542054

20552055
Expr *Op = E->getSubExpr();
20562056
if (Op->getType()->isAnyComplexType()) {
2057+
mlir::Location Loc = CGF.getLoc(E->getExprLoc());
2058+
20572059
// If it's an l-value, load through the appropriate subobject l-value.
20582060
// Note that we have to ask E because Op might be an l-value that
20592061
// this won't work for, e.g. an Obj-C property.
20602062
if (E->isGLValue()) {
2061-
mlir::Location Loc = CGF.getLoc(E->getExprLoc());
20622063
mlir::Value Complex = CGF.emitComplexExpr(Op);
20632064
return CGF.builder.createComplexReal(Loc, Complex);
20642065
}
2066+
20652067
// Otherwise, calculate and project.
2066-
llvm_unreachable("NYI");
2068+
return Builder.createComplexReal(Loc, CGF.emitComplexExpr(Op));
20672069
}
20682070

20692071
return Visit(Op);

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,27 @@ void complex_abstract_condition(bool cond, int _Complex a, int _Complex b) {
4949
// LLVM: [[END_BB]]:
5050
// LLVM: %[[RESULT_VAL:.*]] = phi { i32, i32 } [ %[[TMP_B]], %[[FALSE_BB]] ], [ %[[TMP_A]], %[[TRUE_BB]] ]
5151
// LLVM: store { i32, i32 } %[[RESULT_VAL]], ptr %[[RESULT]], align 4
52+
53+
int _Complex complex_real_operator_on_rvalue() {
54+
int real = __real__ complex_real_operator_on_rvalue();
55+
return {};
56+
}
57+
58+
// CIR: %[[RET_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["__retval"]
59+
// CIR: %[[REAL_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["real", init]
60+
// CIR: %[[CALL:.*]] = cir.call @_Z31complex_real_operator_on_rvaluev() : () -> !cir.complex<!s32i>
61+
// CIR: %[[REAL:.*]] = cir.complex.real %[[CALL]] : !cir.complex<!s32i> -> !s32i
62+
// CIR: cir.store{{.*}} %[[REAL]], %[[REAL_ADDR]] : !s32i, !cir.ptr<!s32i>
63+
// CIR: %[[RET_COMPLEX:.*]] = cir.const #cir.complex<#cir.int<0> : !s32i, #cir.int<0> : !s32i> : !cir.complex<!s32i>
64+
// CIR: cir.store{{.*}} %[[RET_COMPLEX]], %[[RET_ADDR]] : !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>
65+
// CIR: %[[TMP_RET:.*]] = cir.load %[[RET_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
66+
// CIR: cir.return %[[TMP_RET]] : !cir.complex<!s32i>
67+
68+
// LLVM: %[[RET_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
69+
// LLVM: %[[REAL_ADDR:.*]] = alloca i32, i64 1, align 4
70+
// LLVM: %[[CALL:.*]] = call { i32, i32 } @_Z31complex_real_operator_on_rvaluev()
71+
// LLVM: %[[REAL:.*]] = extractvalue { i32, i32 } %[[CALL]], 0
72+
// LLVM: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4
73+
// LLVM: store { i32, i32 } zeroinitializer, ptr %[[RET_ADDR]], align 4
74+
// LLVM: %[[TMP_RET:.*]] = load { i32, i32 }, ptr %[[RET_ADDR]], align 4
75+
// LLVM: ret { i32, i32 } %[[TMP_RET]]

0 commit comments

Comments
 (0)