Skip to content

Commit 24e9e75

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

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
@@ -2070,9 +2070,11 @@ mlir::Value ScalarExprEmitter::VisitImag(const UnaryOperator *E) {
20702070
// If it's an l-value, load through the appropriate subobject l-value.
20712071
// Note that we have to ask E because Op might be an l-value that
20722072
// this won't work for, e.g. an Obj-C property.
2073-
if (E->isGLValue())
2074-
return CGF.emitLoadOfLValue(CGF.emitLValue(E), E->getExprLoc())
2075-
.getScalarVal();
2073+
if (E->isGLValue()) {
2074+
mlir::Location Loc = CGF.getLoc(E->getExprLoc());
2075+
mlir::Value Complex = CGF.emitComplexExpr(Op);
2076+
return CGF.builder.createComplexImag(Loc, Complex);
2077+
}
20762078
// Otherwise, calculate and project.
20772079
llvm_unreachable("NYI");
20782080
}

clang/test/CIR/CodeGen/complex.c

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

345345
// CHECK-BEFORE: cir.func
346346
// CHECK-BEFORE: %[[#C_PTR:]] = cir.get_global @c : !cir.ptr<!cir.complex<!cir.double>>
347-
// CHECK-BEFORE-NEXT: %[[#IMAG_PTR:]] = cir.complex.imag_ptr %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
348-
// CHECK-BEFORE-NEXT: %{{.+}} = cir.load{{.*}} %[[#IMAG_PTR]] : !cir.ptr<!cir.double>, !cir.double
347+
// CHECK-BEFORE-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
348+
// CHECK-BEFORE-NEXT: %[[#IMAG:]] = cir.complex.imag %[[COMPLEX]] : !cir.complex<!cir.double> -> !cir.double
349349
// CHECK-BEFORE: %[[#CI_PTR:]] = cir.get_global @ci : !cir.ptr<!cir.complex<!s32i>>
350-
// CHECK-BEFORE-NEXT: %[[#IMAG_PTR:]] = cir.complex.imag_ptr %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>> -> !cir.ptr<!s32i>
351-
// CHECK-BEFORE-NEXT: %{{.+}} = cir.load{{.*}} %[[#IMAG_PTR]] : !cir.ptr<!s32i>, !s32i
350+
// CHECK-BEFORE-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
351+
// CHECK-BEFORE-NEXT: %[[#IMAG:]] = cir.complex.imag %[[COMPLEX]] : !cir.complex<!s32i> -> !s32i
352352
// CHECK-BEFORE: }
353353

354354
// CHECK-AFTER: cir.func
355355
// CHECK-AFTER: %[[#C_PTR:]] = cir.get_global @c : !cir.ptr<!cir.complex<!cir.double>>
356-
// CHECK-AFTER-NEXT: %[[#IMAG_PTR:]] = cir.complex.imag_ptr %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
357-
// CHECK-AFTER-NEXT: %{{.+}} = cir.load{{.*}} %[[#IMAG_PTR]] : !cir.ptr<!cir.double>, !cir.double
356+
// CHECK-AFTER-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#C_PTR]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
357+
// CHECK-AFTER-NEXT: %[[#IMAG:]] = cir.complex.imag %[[COMPLEX]] : !cir.complex<!cir.double> -> !cir.double
358358
// CHECK-AFTER: %[[#CI_PTR:]] = cir.get_global @ci : !cir.ptr<!cir.complex<!s32i>>
359-
// CHECK-AFTER-NEXT: %[[#IMAG_PTR:]] = cir.complex.imag_ptr %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>> -> !cir.ptr<!s32i>
360-
// CHECK-AFTER-NEXT: %{{.+}} = cir.load{{.*}} %[[#IMAG_PTR]] : !cir.ptr<!s32i>, !s32i
359+
// CHECK-AFTER-NEXT: %[[COMPLEX:.*]] = cir.load{{.*}} %[[#CI_PTR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
360+
// CHECK-AFTER-NEXT: %[[#IMAG:]] = cir.complex.imag %[[COMPLEX]] : !cir.complex<!s32i> -> !s32i
361361
// CHECK-AFTER: }
362362

363-
// Note: GEP emitted by cir might not be the same as LLVM, due to constant folding.
364363
// LLVM: define dso_local void @extract_imag()
365-
// LLVM: %{{.+}} = load double, ptr getelementptr inbounds nuw (i8, ptr @c, i64 8), align 8
366-
// LLVM: %{{.+}} = load i32, ptr getelementptr inbounds nuw (i8, ptr @ci, i64 4), align 4
364+
// LLVM: %[[COMPLEX_D:.*]] = load { double, double }, ptr @c, align 8
365+
// LLVM: %[[I1:.*]] = extractvalue { double, double } %[[COMPLEX_D]], 1
366+
// LLVM: %[[COMPLEX_I:.*]] = load { i32, i32 }, ptr @ci, align 4
367+
// LLVM: %[[I2:.*]] = extractvalue { i32, i32 } %[[COMPLEX_I]], 1
368+
// LLVM: }
369+
370+
int extract_imag_and_add(int _Complex a, int _Complex b) {
371+
return __imag__ a + __imag__ b;
372+
}
373+
374+
// CHECK-BEFORE: cir.func
375+
// CHECK-BEFORE: %[[COMPLEX_A:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
376+
// CHECK-BEFORE-NEXT: %[[IMAG_A:.*]] = cir.complex.imag %[[COMPLEX_A]] : !cir.complex<!s32i> -> !s32i
377+
// CHECK-BEFORE-NEXT: %[[COMPLEX_B:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
378+
// CHECK-BEFORE-NEXT: %[[IMAG_B:.*]] = cir.complex.imag %[[COMPLEX_B]] : !cir.complex<!s32i> -> !s32i
379+
// CHECK-BEFORE-NEXT: %[[ADD:.*]] = cir.binop(add, %[[IMAG_A]], %[[IMAG_B]]) nsw : !s32i
380+
// CHECK-BEFORE: }
381+
382+
// CHECK-AFTER: cir.func
383+
// CHECK-AFTER: %[[COMPLEX_A:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
384+
// CHECK-AFTER-NEXT: %[[IMAG_A:.*]] = cir.complex.imag %[[COMPLEX_A]] : !cir.complex<!s32i> -> !s32i
385+
// CHECK-AFTER-NEXT: %[[COMPLEX_B:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
386+
// CHECK-AFTER-NEXT: %[[IMAG_B:.*]] = cir.complex.imag %[[COMPLEX_B]] : !cir.complex<!s32i> -> !s32i
387+
// CHECK-AFTER-NEXT: %[[ADD:.*]] = cir.binop(add, %[[IMAG_A]], %[[IMAG_B]]) nsw : !s32i
388+
// CHECK-AFTER: }
389+
390+
// LLVM: define dso_local i32 @extract_imag_and_add
391+
// LLVM: %[[COMPLEX_A:.*]] = load { i32, i32 }, ptr {{.*}}, align 4
392+
// LLVM: %[[IMAG_A:.*]] = extractvalue { i32, i32 } %[[COMPLEX_A]], 1
393+
// LLVM: %[[COMPLEX_B:.*]] = load { i32, i32 }, ptr {{.*}}, align 4
394+
// LLVM: %[[IMAG_B:.*]] = extractvalue { i32, i32 } %[[COMPLEX_B]], 1
395+
// LLVM: %10 = add nsw i32 %[[IMAG_A]], %[[IMAG_B]]
367396
// LLVM: }
368397

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

0 commit comments

Comments
 (0)