Skip to content

Commit f4ceabd

Browse files
committed
[CIR] Upstream Unary Inc/Dec for ComplexType
1 parent bd0f9dd commit f4ceabd

File tree

4 files changed

+254
-2
lines changed

4 files changed

+254
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
5656
mlir::Value VisitParenExpr(ParenExpr *e);
5757
mlir::Value
5858
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e);
59+
60+
mlir::Value VisitPrePostIncDec(const UnaryOperator *e, bool isInc,
61+
bool isPre);
62+
63+
mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {
64+
return VisitPrePostIncDec(e, false, false);
65+
}
66+
67+
mlir::Value VisitUnaryPostInc(const UnaryOperator *e) {
68+
return VisitPrePostIncDec(e, true, false);
69+
}
70+
71+
mlir::Value VisitUnaryPreDec(const UnaryOperator *e) {
72+
return VisitPrePostIncDec(e, false, true);
73+
}
74+
75+
mlir::Value VisitUnaryPreInc(const UnaryOperator *e) {
76+
return VisitPrePostIncDec(e, true, true);
77+
}
78+
5979
mlir::Value VisitUnaryDeref(const Expr *e);
6080
mlir::Value VisitUnaryNot(const UnaryOperator *e);
6181

@@ -335,6 +355,12 @@ mlir::Value ComplexExprEmitter::VisitSubstNonTypeTemplateParmExpr(
335355
return Visit(e->getReplacement());
336356
}
337357

358+
mlir::Value ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *e,
359+
bool isInc, bool isPre) {
360+
LValue lv = cgf.emitLValue(e->getSubExpr());
361+
return cgf.emitComplexPrePostIncDec(e, lv, isInc, isPre);
362+
}
363+
338364
mlir::Value ComplexExprEmitter::VisitUnaryDeref(const Expr *e) {
339365
return emitLoadOfLValue(e);
340366
}
@@ -423,6 +449,29 @@ mlir::Value CIRGenFunction::emitComplexExpr(const Expr *e) {
423449
return ComplexExprEmitter(*this).Visit(const_cast<Expr *>(e));
424450
}
425451

452+
mlir::Value CIRGenFunction::emitComplexPrePostIncDec(const UnaryOperator *e,
453+
LValue lv, bool isInc,
454+
bool isPre) {
455+
mlir::Value inVal = emitLoadOfComplex(lv, e->getExprLoc());
456+
mlir::Location loc = getLoc(e->getExprLoc());
457+
auto opKind = isInc ? cir::UnaryOpKind::Inc : cir::UnaryOpKind::Dec;
458+
mlir::Value incVal = builder.createUnaryOp(loc, opKind, inVal);
459+
460+
// Store the updated result through the lvalue.
461+
emitStoreOfComplex(loc, incVal, lv, /*isInit=*/false);
462+
463+
if (getLangOpts().OpenMP)
464+
cgm.errorNYI(loc, "emitComplexPrePostIncDec OpenMP");
465+
466+
// If this is a postinc, return the value read from memory, otherwise use the
467+
// updated value.
468+
return isPre ? incVal : inVal;
469+
}
470+
471+
mlir::Value CIRGenFunction::emitLoadOfComplex(LValue src, SourceLocation loc) {
472+
return ComplexExprEmitter(*this).emitLoadOfLValue(src, loc);
473+
}
474+
426475
void CIRGenFunction::emitStoreOfComplex(mlir::Location loc, mlir::Value v,
427476
LValue dest, bool isInit) {
428477
ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit);

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,9 @@ class CIRGenFunction : public CIRGenTypeCache {
930930
/// returning the result.
931931
mlir::Value emitComplexExpr(const Expr *e);
932932

933+
mlir::Value emitComplexPrePostIncDec(const UnaryOperator *e, LValue lv,
934+
bool isInc, bool isPre);
935+
933936
LValue emitComplexAssignmentLValue(const BinaryOperator *e);
934937

935938
void emitCompoundStmt(const clang::CompoundStmt &s);
@@ -980,6 +983,9 @@ class CIRGenFunction : public CIRGenTypeCache {
980983

981984
RValue emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc);
982985

986+
/// Load a complex number from the specified l-value.
987+
mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc);
988+
983989
/// Given an expression that represents a value lvalue, this method emits
984990
/// the address of the lvalue, then loads the result as an rvalue,
985991
/// returning the rvalue.

clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ void LoweringPreparePass::lowerUnaryOp(cir::UnaryOp op) {
5050
switch (opKind) {
5151
case cir::UnaryOpKind::Inc:
5252
case cir::UnaryOpKind::Dec:
53-
llvm_unreachable("Complex unary Inc/Dec NYI");
53+
resultReal = builder.createUnaryOp(loc, opKind, operandReal);
54+
resultImag = operandImag;
5455
break;
5556

5657
case cir::UnaryOpKind::Plus:

clang/test/CIR/CodeGen/complex-unary.cpp

Lines changed: 197 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,204 @@ void foo2() {
8383
// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4
8484
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 1
8585
// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4
86-
// OGCG: %[[A_IMAG_MINUS:.*]] = fneg float %[[A_IMAG]]
86+
// OGCG: %[[A_IMAG_MINUS:.*]] = fneg float %[[A_IMAG]]
8787
// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 0
8888
// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 1
8989
// OGCG: store float %[[A_REAL]], ptr %[[RESULT_REAL_PTR]], align 4
9090
// OGCG: store float %[[A_IMAG_MINUS]], ptr %[[RESULT_IMAG_PTR]], align 4
91+
92+
void foo3() {
93+
float _Complex a;
94+
float _Complex b = a++;
95+
}
96+
97+
// CIR-BEFORE: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]
98+
// CIR-BEFORE: %[[RESULT:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init]
99+
// CIR-BEFORE: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
100+
// CIR-BEFORE: %[[COMPLEX_INC:.*]] = cir.unary(inc, %[[TMP]]) : !cir.complex<!cir.float>, !cir.complex<!cir.float>
101+
// CIR-BEFORE: cir.store{{.*}} %[[COMPLEX_INC]], %[[COMPLEX]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
102+
// CIR-BEFORE: cir.store{{.*}} %[[TMP]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
103+
104+
// CIR-AFTER: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]
105+
// CIR-AFTER: %[[RESULT:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init]
106+
// CIR-AFTER: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
107+
// CIR-AFTER: %[[REAL:.*]] = cir.complex.real %[[TMP]] : !cir.complex<!cir.float> -> !cir.float
108+
// CIR-AFTER: %[[IMAG:.*]] = cir.complex.imag %[[TMP]] : !cir.complex<!cir.float> -> !cir.float
109+
// CIR-AFTER: %[[REAL_INC:.*]] = cir.unary(inc, %[[REAL]]) : !cir.float, !cir.float
110+
// CIR-AFTER: %[[NEW_COMPLEX:.*]] = cir.complex.create %[[REAL_INC]], %[[IMAG]] : !cir.float -> !cir.complex<!cir.float>
111+
// CIR-AFTER: cir.store{{.*}} %[[NEW_COMPLEX]], %[[COMPLEX]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
112+
// CIR-AFTER: cir.store{{.*}} %[[TMP]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
113+
114+
// LLVM: %[[COMPLEX:.*]] = alloca { float, float }, i64 1, align 4
115+
// LLVM: %[[RESULT:.*]] = alloca { float, float }, i64 1, align 4
116+
// LLVM: %[[TMP:.*]] = load { float, float }, ptr %[[COMPLEX]], align 4
117+
// LLVM: %[[REAL:.*]] = extractvalue { float, float } %[[TMP]], 0
118+
// LLVM: %[[IMAG:.*]] = extractvalue { float, float } %[[TMP]], 1
119+
// LLVM: %[[REAL_INC:.*]] = fadd float 1.000000e+00, %[[REAL]]
120+
// LLVM: %[[RESULT_TMP:.*]] = insertvalue { float, float } {{.*}}, float %[[REAL_INC]], 0
121+
// LLVM: %[[RESULT_VAL:.*]] = insertvalue { float, float } %[[RESULT_TMP]], float %[[IMAG]], 1
122+
// LLVM: store { float, float } %[[RESULT_VAL]], ptr %[[COMPLEX]], align 4
123+
// LLVM: store { float, float } %[[TMP]], ptr %[[RESULT]], align 4
124+
125+
// OGCG: %[[COMPLEX:.*]] = alloca { float, float }, align 4
126+
// OGCG: %[[RESULT:.*]] = alloca { float, float }, align 4
127+
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 0
128+
// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4
129+
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 1
130+
// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4
131+
// OGCG: %[[A_REAL_INC:.*]] = fadd float %[[A_REAL]], 1.000000e+00
132+
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 0
133+
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 1
134+
// OGCG: store float %[[A_REAL_INC]], ptr %[[A_REAL_PTR]], align 4
135+
// OGCG: store float %[[A_IMAG]], ptr %[[A_IMAG_PTR]], align 4
136+
// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 0
137+
// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 1
138+
// OGCG: store float %[[A_REAL]], ptr %[[RESULT_REAL_PTR]], align 4
139+
// OGCG: store float %[[A_IMAG]], ptr %[[RESULT_IMAG_PTR]], align 4
140+
141+
void foo4() {
142+
float _Complex a;
143+
float _Complex b = ++a;
144+
}
145+
146+
// CIR-BEFORE: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]
147+
// CIR-BEFORE: %[[RESULT:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init]
148+
// CIR-BEFORE: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
149+
// CIR-BEFORE: %[[COMPLEX_INC:.*]] = cir.unary(inc, %[[TMP]]) : !cir.complex<!cir.float>, !cir.complex<!cir.float>
150+
// CIR-BEFORE: cir.store{{.*}} %[[COMPLEX_INC]], %[[COMPLEX]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
151+
// CIR-BEFORE: cir.store{{.*}} %[[COMPLEX_INC]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
152+
153+
// CIR-AFTER: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]
154+
// CIR-AFTER: %[[RESULT:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init]
155+
// CIR-AFTER: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
156+
// CIR-AFTER: %[[REAL:.*]] = cir.complex.real %[[TMP]] : !cir.complex<!cir.float> -> !cir.float
157+
// CIR-AFTER: %[[IMAG:.*]] = cir.complex.imag %[[TMP]] : !cir.complex<!cir.float> -> !cir.float
158+
// CIR-AFTER: %[[REAL_INC:.*]] = cir.unary(inc, %[[REAL]]) : !cir.float, !cir.float
159+
// CIR-AFTER: %[[NEW_COMPLEX:.*]] = cir.complex.create %[[REAL_INC]], %[[IMAG]] : !cir.float -> !cir.complex<!cir.float>
160+
// CIR-AFTER: cir.store{{.*}} %[[NEW_COMPLEX]], %[[COMPLEX]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
161+
// CIR-AFTER: cir.store{{.*}} %[[NEW_COMPLEX]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
162+
163+
// LLVM: %[[COMPLEX:.*]] = alloca { float, float }, i64 1, align 4
164+
// LLVM: %[[RESULT:.*]] = alloca { float, float }, i64 1, align 4
165+
// LLVM: %[[TMP:.*]] = load { float, float }, ptr %[[COMPLEX]], align 4
166+
// LLVM: %[[REAL:.*]] = extractvalue { float, float } %[[TMP]], 0
167+
// LLVM: %[[IMAG:.*]] = extractvalue { float, float } %[[TMP]], 1
168+
// LLVM: %[[REAL_INC:.*]] = fadd float 1.000000e+00, %[[REAL]]
169+
// LLVM: %[[RESULT_TMP:.*]] = insertvalue { float, float } {{.*}}, float %[[REAL_INC]], 0
170+
// LLVM: %[[RESULT_VAL:.*]] = insertvalue { float, float } %[[RESULT_TMP]], float %[[IMAG]], 1
171+
// LLVM: store { float, float } %[[RESULT_VAL]], ptr %[[COMPLEX]], align 4
172+
// LLVM: store { float, float } %[[RESULT_VAL]], ptr %[[RESULT]], align 4
173+
174+
// OGCG: %[[COMPLEX:.*]] = alloca { float, float }, align 4
175+
// OGCG: %[[RESULT:.*]] = alloca { float, float }, align 4
176+
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 0
177+
// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4
178+
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 1
179+
// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4
180+
// OGCG: %[[A_REAL_INC:.*]] = fadd float %[[A_REAL]], 1.000000e+00
181+
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 0
182+
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 1
183+
// OGCG: store float %[[A_REAL_INC]], ptr %[[A_REAL_PTR]], align 4
184+
// OGCG: store float %[[A_IMAG]], ptr %[[A_IMAG_PTR]], align 4
185+
// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 0
186+
// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 1
187+
// OGCG: store float %[[A_REAL_INC]], ptr %[[RESULT_REAL_PTR]], align 4
188+
// OGCG: store float %[[A_IMAG]], ptr %[[RESULT_IMAG_PTR]], align 4
189+
190+
void foo5() {
191+
float _Complex a;
192+
float _Complex b = a--;
193+
}
194+
195+
// CIR-BEFORE: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]
196+
// CIR-BEFORE: %[[RESULT:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init]
197+
// CIR-BEFORE: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
198+
// CIR-BEFORE: %[[COMPLEX_DEC:.*]] = cir.unary(dec, %[[TMP]]) : !cir.complex<!cir.float>, !cir.complex<!cir.float>
199+
// CIR-BEFORE: cir.store{{.*}} %[[COMPLEX_DEC]], %[[COMPLEX]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
200+
// CIR-BEFORE: cir.store{{.*}} %[[TMP]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
201+
202+
// CIR-AFTER: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]
203+
// CIR-AFTER: %[[RESULT:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init]
204+
// CIR-AFTER: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
205+
// CIR-AFTER: %[[REAL:.*]] = cir.complex.real %[[TMP]] : !cir.complex<!cir.float> -> !cir.float
206+
// CIR-AFTER: %[[IMAG:.*]] = cir.complex.imag %[[TMP]] : !cir.complex<!cir.float> -> !cir.float
207+
// CIR-AFTER: %[[REAL_DEC:.*]] = cir.unary(dec, %[[REAL]]) : !cir.float, !cir.float
208+
// CIR-AFTER: %[[NEW_COMPLEX:.*]] = cir.complex.create %[[REAL_DEC]], %[[IMAG]] : !cir.float -> !cir.complex<!cir.float>
209+
// CIR-AFTER: cir.store{{.*}} %[[NEW_COMPLEX]], %[[COMPLEX]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
210+
// CIR-AFTER: cir.store{{.*}} %[[TMP]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
211+
212+
// LLVM: %[[COMPLEX:.*]] = alloca { float, float }, i64 1, align 4
213+
// LLVM: %[[RESULT:.*]] = alloca { float, float }, i64 1, align 4
214+
// LLVM: %[[TMP:.*]] = load { float, float }, ptr %[[COMPLEX]], align 4
215+
// LLVM: %[[REAL:.*]] = extractvalue { float, float } %[[TMP]], 0
216+
// LLVM: %[[IMAG:.*]] = extractvalue { float, float } %[[TMP]], 1
217+
// LLVM: %[[REAL_DEC:.*]] = fadd float -1.000000e+00, %[[REAL]]
218+
// LLVM: %[[RESULT_TMP:.*]] = insertvalue { float, float } {{.*}}, float %[[REAL_DEC]], 0
219+
// LLVM: %[[RESULT_VAL:.*]] = insertvalue { float, float } %[[RESULT_TMP]], float %[[IMAG]], 1
220+
// LLVM: store { float, float } %[[RESULT_VAL]], ptr %[[COMPLEX]], align 4
221+
// LLVM: store { float, float } %[[TMP]], ptr %[[RESULT]], align 4
222+
223+
// OGCG: %[[COMPLEX:.*]] = alloca { float, float }, align 4
224+
// OGCG: %[[RESULT:.*]] = alloca { float, float }, align 4
225+
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 0
226+
// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4
227+
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 1
228+
// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4
229+
// OGCG: %[[A_REAL_DEC:.*]] = fadd float %[[A_REAL]], -1.000000e+00
230+
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 0
231+
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 1
232+
// OGCG: store float %[[A_REAL_DEC]], ptr %[[A_REAL_PTR]], align 4
233+
// OGCG: store float %[[A_IMAG]], ptr %[[A_IMAG_PTR]], align 4
234+
// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 0
235+
// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 1
236+
// OGCG: store float %[[A_REAL]], ptr %[[RESULT_REAL_PTR]], align 4
237+
// OGCG: store float %[[A_IMAG]], ptr %[[RESULT_IMAG_PTR]], align 4
238+
239+
void foo6() {
240+
float _Complex a;
241+
float _Complex b = --a;
242+
}
243+
244+
// CIR-BEFORE: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]
245+
// CIR-BEFORE: %[[RESULT:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init]
246+
// CIR-BEFORE: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
247+
// CIR-BEFORE: %[[COMPLEX_DEC:.*]] = cir.unary(dec, %[[TMP]]) : !cir.complex<!cir.float>, !cir.complex<!cir.float>
248+
// CIR-BEFORE: cir.store{{.*}} %[[COMPLEX_DEC]], %[[COMPLEX]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
249+
// CIR-BEFORE: cir.store{{.*}} %[[COMPLEX_DEC]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
250+
251+
// CIR-AFTER: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]
252+
// CIR-AFTER: %[[RESULT:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init]
253+
// CIR-AFTER: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
254+
// CIR-AFTER: %[[REAL:.*]] = cir.complex.real %[[TMP]] : !cir.complex<!cir.float> -> !cir.float
255+
// CIR-AFTER: %[[IMAG:.*]] = cir.complex.imag %[[TMP]] : !cir.complex<!cir.float> -> !cir.float
256+
// CIR-AFTER: %[[REAL_DEC:.*]] = cir.unary(dec, %[[REAL]]) : !cir.float, !cir.float
257+
// CIR-AFTER: %[[NEW_COMPLEX:.*]] = cir.complex.create %[[REAL_DEC]], %[[IMAG]] : !cir.float -> !cir.complex<!cir.float>
258+
// CIR-AFTER: cir.store{{.*}} %[[NEW_COMPLEX]], %[[COMPLEX]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
259+
// CIR-AFTER: cir.store{{.*}} %[[NEW_COMPLEX]], %[[RESULT]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
260+
261+
// LLVM: %[[COMPLEX:.*]] = alloca { float, float }, i64 1, align 4
262+
// LLVM: %[[RESULT:.*]] = alloca { float, float }, i64 1, align 4
263+
// LLVM: %[[TMP:.*]] = load { float, float }, ptr %[[COMPLEX]], align 4
264+
// LLVM: %[[REAL:.*]] = extractvalue { float, float } %[[TMP]], 0
265+
// LLVM: %[[IMAG:.*]] = extractvalue { float, float } %[[TMP]], 1
266+
// LLVM: %[[REAL_DEC:.*]] = fadd float -1.000000e+00, %[[REAL]]
267+
// LLVM: %[[RESULT_TMP:.*]] = insertvalue { float, float } {{.*}}, float %[[REAL_DEC]], 0
268+
// LLVM: %[[RESULT_VAL:.*]] = insertvalue { float, float } %[[RESULT_TMP]], float %[[IMAG]], 1
269+
// LLVM: store { float, float } %[[RESULT_VAL]], ptr %[[COMPLEX]], align 4
270+
// LLVM: store { float, float } %[[RESULT_VAL]], ptr %[[RESULT]], align 4
271+
272+
// OGCG: %[[COMPLEX:.*]] = alloca { float, float }, align 4
273+
// OGCG: %[[RESULT:.*]] = alloca { float, float }, align 4
274+
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 0
275+
// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4
276+
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 1
277+
// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4
278+
// OGCG: %[[A_REAL_DEC:.*]] = fadd float %[[A_REAL]], -1.000000e+00
279+
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 0
280+
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[COMPLEX]], i32 0, i32 1
281+
// OGCG: store float %[[A_REAL_DEC]], ptr %[[A_REAL_PTR]], align 4
282+
// OGCG: store float %[[A_IMAG]], ptr %[[A_IMAG_PTR]], align 4
283+
// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 0
284+
// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[RESULT]], i32 0, i32 1
285+
// OGCG: store float %[[A_REAL_DEC]], ptr %[[RESULT_REAL_PTR]], align 4
286+
// OGCG: store float %[[A_IMAG]], ptr %[[RESULT_IMAG_PTR]], align 4

0 commit comments

Comments
 (0)