Skip to content

Commit 31c0728

Browse files
authored
[CIR] Use ComplexRealOp for RValue __real__ operator (#1689)
Update `__real__` operation to use ComplexRealOp and act directly on the complex value. Ref: llvm/llvm-project#144235 (review)
1 parent 076219a commit 31c0728

File tree

2 files changed

+45
-13
lines changed

2 files changed

+45
-13
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,9 +2050,11 @@ mlir::Value ScalarExprEmitter::VisitReal(const UnaryOperator *E) {
20502050
// If it's an l-value, load through the appropriate subobject l-value.
20512051
// Note that we have to ask E because Op might be an l-value that
20522052
// this won't work for, e.g. an Obj-C property.
2053-
if (E->isGLValue())
2054-
return CGF.emitLoadOfLValue(CGF.emitLValue(E), E->getExprLoc())
2055-
.getScalarVal();
2053+
if (E->isGLValue()) {
2054+
mlir::Location Loc = CGF.getLoc(E->getExprLoc());
2055+
mlir::Value Complex = CGF.emitComplexExpr(Op);
2056+
return CGF.builder.createComplexReal(Loc, Complex);
2057+
}
20562058
// Otherwise, calculate and project.
20572059
llvm_unreachable("NYI");
20582060
}

clang/test/CIR/CodeGen/complex.c

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -261,25 +261,55 @@ void extract_real() {
261261

262262
// CHECK-BEFORE: cir.func
263263
// CHECK-BEFORE: %[[#C_PTR:]] = cir.get_global @c : !cir.ptr<!cir.complex<!cir.double>>
264-
// CHECK-BEFORE-NEXT: %[[#REAL_PTR:]] = cir.complex.real_ptr %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
265-
// CHECK-BEFORE-NEXT: %{{.+}} = cir.load{{.*}} %[[#REAL_PTR]] : !cir.ptr<!cir.double>, !cir.double
264+
// CHECK-BEFORE-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
265+
// CHECK-BEFORE-NEXT: %[[#REAL:]] = cir.complex.real %[[COMPLEX]] : !cir.complex<!cir.double> -> !cir.double
266266
// CHECK-BEFORE: %[[#CI_PTR:]] = cir.get_global @ci : !cir.ptr<!cir.complex<!s32i>>
267-
// CHECK-BEFORE-NEXT: %[[#REAL_PTR:]] = cir.complex.real_ptr %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>> -> !cir.ptr<!s32i>
268-
// CHECK-BEFORE-NEXT: %{{.+}} = cir.load{{.*}} %[[#REAL_PTR]] : !cir.ptr<!s32i>, !s32i
267+
// CHECK-BEFORE-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
268+
// CHECK-BEFORE-NEXT: %[[#REAL:]] = cir.complex.real %[[COMPLEX]] : !cir.complex<!s32i> -> !s32i
269269
// CHECK-BEFORE: }
270270

271271
// CHECK-AFTER: cir.func
272272
// CHECK-AFTER: %[[#C_PTR:]] = cir.get_global @c : !cir.ptr<!cir.complex<!cir.double>>
273-
// CHECK-AFTER-NEXT: %[[#REAL_PTR:]] = cir.complex.real_ptr %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
274-
// CHECK-AFTER-NEXT: %{{.+}} = cir.load{{.*}} %[[#REAL_PTR]] : !cir.ptr<!cir.double>, !cir.double
273+
// CHECK-AFTER-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
274+
// CHECK-AFTER-NEXT: %[[#REAL:]] = cir.complex.real %[[COMPLEX]] : !cir.complex<!cir.double> -> !cir.double
275275
// CHECK-AFTER: %[[#CI_PTR:]] = cir.get_global @ci : !cir.ptr<!cir.complex<!s32i>>
276-
// CHECK-AFTER-NEXT: %[[#REAL_PTR:]] = cir.complex.real_ptr %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>> -> !cir.ptr<!s32i>
277-
// CHECK-AFTER-NEXT: %{{.+}} = cir.load{{.*}} %[[#REAL_PTR]] : !cir.ptr<!s32i>, !s32i
276+
// CHECK-AFTER-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
277+
// CHECK-AFTER-NEXT: %[[#REAL:]] = cir.complex.real %[[COMPLEX]] : !cir.complex<!s32i> -> !s32i
278278
// CHECK-AFTER: }
279279

280280
// LLVM: define dso_local void @extract_real()
281-
// LLVM: %{{.+}} = load double, ptr @c, align 8
282-
// LLVM: %{{.+}} = load i32, ptr @ci, align 4
281+
// LLVM: %[[COMPLEX_D:.*]] = load { double, double }, ptr @c, align 8
282+
// LLVM: %[[R1:.*]] = extractvalue { double, double } %[[COMPLEX_D]], 0
283+
// LLVM: %[[COMPLEX_I:.*]] = load { i32, i32 }, ptr @ci, align 4
284+
// LLVM: %[[R2:.*]] = extractvalue { i32, i32 } %[[COMPLEX_I]], 0
285+
// LLVM: }
286+
287+
int extract_real_and_add(int _Complex a, int _Complex b) {
288+
return __real__ a + __real__ b;
289+
}
290+
291+
// CHECK-BEFORE: cir.func
292+
// CHECK-BEFORE: %[[COMPLEX_A:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
293+
// CHECK-BEFORE-NEXT: %[[REAL_A:.*]] = cir.complex.real %[[COMPLEX_A]] : !cir.complex<!s32i> -> !s32i
294+
// CHECK-BEFORE-NEXT: %[[COMPLEX_B:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
295+
// CHECK-BEFORE-NEXT: %[[REAL_B:.*]] = cir.complex.real %[[COMPLEX_B]] : !cir.complex<!s32i> -> !s32i
296+
// CHECK-BEFORE-NEXT: %[[ADD:.*]] = cir.binop(add, %[[REAL_A]], %[[REAL_B]]) nsw : !s32i
297+
// CHECK-BEFORE: }
298+
299+
// CHECK-AFTER: cir.func
300+
// CHECK-AFTER: %[[COMPLEX_A:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
301+
// CHECK-AFTER-NEXT: %[[REAL_A:.*]] = cir.complex.real %[[COMPLEX_A]] : !cir.complex<!s32i> -> !s32i
302+
// CHECK-AFTER-NEXT: %[[COMPLEX_B:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
303+
// CHECK-AFTER-NEXT: %[[REAL_B:.*]] = cir.complex.real %[[COMPLEX_B]] : !cir.complex<!s32i> -> !s32i
304+
// CHECK-AFTER-NEXT: %[[ADD:.*]] = cir.binop(add, %[[REAL_A]], %[[REAL_B]]) nsw : !s32i
305+
// CHECK-AFTER: }
306+
307+
// LLVM: define dso_local i32 @extract_real_and_add
308+
// LLVM: %[[COMPLEX_A:.*]] = load { i32, i32 }, ptr {{.*}}, align 4
309+
// LLVM: %[[REAL_A:.*]] = extractvalue { i32, i32 } %[[COMPLEX_A]], 0
310+
// LLVM: %[[COMPLEX_B:.*]] = load { i32, i32 }, ptr {{.*}}, align 4
311+
// LLVM: %[[REAL_B:.*]] = extractvalue { i32, i32 } %[[COMPLEX_B]], 0
312+
// LLVM: %10 = add nsw i32 %[[REAL_A]], %[[REAL_B]]
283313
// LLVM: }
284314

285315
void imag_ptr() {

0 commit comments

Comments
 (0)