Skip to content

Commit 917a6d2

Browse files
committed
[CIR] Use ComplexRealOp for RValue __imag__ operator
1 parent 74f16f7 commit 917a6d2

File tree

2 files changed

+45
-14
lines changed

2 files changed

+45
-14
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,9 +2068,11 @@ mlir::Value ScalarExprEmitter::VisitImag(const UnaryOperator *E) {
20682068
// If it's an l-value, load through the appropriate subobject l-value.
20692069
// Note that we have to ask E because Op might be an l-value that
20702070
// this won't work for, e.g. an Obj-C property.
2071-
if (E->isGLValue())
2072-
return CGF.emitLoadOfLValue(CGF.emitLValue(E), E->getExprLoc())
2073-
.getScalarVal();
2071+
if (E->isGLValue()) {
2072+
mlir::Location Loc = CGF.getLoc(E->getExprLoc());
2073+
mlir::Value Complex = CGF.emitComplexExpr(Op);
2074+
return CGF.builder.createComplexImag(Loc, Complex);
2075+
}
20742076
// Otherwise, calculate and project.
20752077
llvm_unreachable("NYI");
20762078
}

clang/test/CIR/CodeGen/complex.c

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -314,26 +314,55 @@ void extract_imag() {
314314

315315
// CHECK-BEFORE: cir.func
316316
// CHECK-BEFORE: %[[#C_PTR:]] = cir.get_global @c : !cir.ptr<!cir.complex<!cir.double>>
317-
// CHECK-BEFORE-NEXT: %[[#IMAG_PTR:]] = cir.complex.imag_ptr %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
318-
// CHECK-BEFORE-NEXT: %{{.+}} = cir.load{{.*}} %[[#IMAG_PTR]] : !cir.ptr<!cir.double>, !cir.double
317+
// CHECK-BEFORE-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
318+
// CHECK-BEFORE-NEXT: %[[#IMAG:]] = cir.complex.imag %[[COMPLEX]] : !cir.complex<!cir.double> -> !cir.double
319319
// CHECK-BEFORE: %[[#CI_PTR:]] = cir.get_global @ci : !cir.ptr<!cir.complex<!s32i>>
320-
// CHECK-BEFORE-NEXT: %[[#IMAG_PTR:]] = cir.complex.imag_ptr %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>> -> !cir.ptr<!s32i>
321-
// CHECK-BEFORE-NEXT: %{{.+}} = cir.load{{.*}} %[[#IMAG_PTR]] : !cir.ptr<!s32i>, !s32i
320+
// CHECK-BEFORE-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
321+
// CHECK-BEFORE-NEXT: %[[#IMAG:]] = cir.complex.imag %[[COMPLEX]] : !cir.complex<!s32i> -> !s32i
322322
// CHECK-BEFORE: }
323323

324324
// CHECK-AFTER: cir.func
325325
// CHECK-AFTER: %[[#C_PTR:]] = cir.get_global @c : !cir.ptr<!cir.complex<!cir.double>>
326-
// CHECK-AFTER-NEXT: %[[#IMAG_PTR:]] = cir.complex.imag_ptr %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
327-
// CHECK-AFTER-NEXT: %{{.+}} = cir.load{{.*}} %[[#IMAG_PTR]] : !cir.ptr<!cir.double>, !cir.double
326+
// CHECK-AFTER-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
327+
// CHECK-AFTER-NEXT: %[[#IMAG:]] = cir.complex.imag %[[COMPLEX]] : !cir.complex<!cir.double> -> !cir.double
328328
// CHECK-AFTER: %[[#CI_PTR:]] = cir.get_global @ci : !cir.ptr<!cir.complex<!s32i>>
329-
// CHECK-AFTER-NEXT: %[[#IMAG_PTR:]] = cir.complex.imag_ptr %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>> -> !cir.ptr<!s32i>
330-
// CHECK-AFTER-NEXT: %{{.+}} = cir.load{{.*}} %[[#IMAG_PTR]] : !cir.ptr<!s32i>, !s32i
329+
// CHECK-AFTER-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
330+
// CHECK-AFTER-NEXT: %[[#IMAG:]] = cir.complex.imag %[[COMPLEX]] : !cir.complex<!s32i> -> !s32i
331331
// CHECK-AFTER: }
332332

333-
// Note: GEP emitted by cir might not be the same as LLVM, due to constant folding.
334333
// LLVM: define dso_local void @extract_imag()
335-
// LLVM: %{{.+}} = load double, ptr getelementptr inbounds nuw (i8, ptr @c, i64 8), align 8
336-
// LLVM: %{{.+}} = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci, i64 4), align 4
334+
// LLVM: %[[COMPLEX_D:.*]] = load { double, double }, ptr @c, align 8
335+
// LLVM: %[[I1:.*]] = extractvalue { double, double } %[[COMPLEX_D]], 1
336+
// LLVM: %[[COMPLEX_I:.*]] = load { i32, i32 }, ptr @ci, align 4
337+
// LLVM: %[[I2:.*]] = extractvalue { i32, i32 } %[[COMPLEX_I]], 1
338+
// LLVM: }
339+
340+
int extract_imag_and_add(int _Complex a, int _Complex b) {
341+
return __imag__ a + __imag__ b;
342+
}
343+
344+
// CHECK-BEFORE: cir.func
345+
// CHECK-BEFORE: %[[COMPLEX_A:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
346+
// CHECK-BEFORE-NEXT: %[[IMAG_A:.*]] = cir.complex.imag %[[COMPLEX_A]] : !cir.complex<!s32i> -> !s32i
347+
// CHECK-BEFORE-NEXT: %[[COMPLEX_B:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
348+
// CHECK-BEFORE-NEXT: %[[IMAG_B:.*]] = cir.complex.imag %[[COMPLEX_B]] : !cir.complex<!s32i> -> !s32i
349+
// CHECK-BEFORE-NEXT: %[[ADD:.*]] = cir.binop(add, %[[IMAG_A]], %[[IMAG_B]]) nsw : !s32i
350+
// CHECK-BEFORE: }
351+
352+
// CHECK-AFTER: cir.func
353+
// CHECK-AFTER: %[[COMPLEX_A:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
354+
// CHECK-AFTER-NEXT: %[[IMAG_A:.*]] = cir.complex.imag %[[COMPLEX_A]] : !cir.complex<!s32i> -> !s32i
355+
// CHECK-AFTER-NEXT: %[[COMPLEX_B:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
356+
// CHECK-AFTER-NEXT: %[[IMAG_B:.*]] = cir.complex.imag %[[COMPLEX_B]] : !cir.complex<!s32i> -> !s32i
357+
// CHECK-AFTER-NEXT: %[[ADD:.*]] = cir.binop(add, %[[IMAG_A]], %[[IMAG_B]]) nsw : !s32i
358+
// CHECK-AFTER: }
359+
360+
// LLVM: define dso_local i32 @extract_imag_and_add
361+
// LLVM: %[[COMPLEX_A:.*]] = load { i32, i32 }, ptr {{.*}}, align 4
362+
// LLVM: %[[IMAG_A:.*]] = extractvalue { i32, i32 } %[[COMPLEX_A]], 1
363+
// LLVM: %[[COMPLEX_B:.*]] = load { i32, i32 }, ptr {{.*}}, align 4
364+
// LLVM: %[[IMAG_B:.*]] = extractvalue { i32, i32 } %[[COMPLEX_B]], 1
365+
// LLVM: %10 = add nsw i32 %[[IMAG_A]], %[[IMAG_B]]
337366
// LLVM: }
338367

339368
void complex_with_empty_init() { int _Complex c = {}; }

0 commit comments

Comments
 (0)