-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[CIR] Update ComplexImagOp to work on scalar type #161571
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CIR] Update ComplexImagOp to work on scalar type #161571
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clangir Author: Amr Hesham (AmrDeveloper) ChangesUpdate cir::ComplexImagOp to make it visible on scalars Issue #160568 Full diff: https://github.com/llvm/llvm-project/pull/161571.diff 6 Files Affected:
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 8a5bf0376ec98..e02320eef0e3e 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -155,9 +155,10 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
}
mlir::Value createComplexImag(mlir::Location loc, mlir::Value operand) {
- auto operandTy = mlir::cast<cir::ComplexType>(operand.getType());
- return cir::ComplexImagOp::create(*this, loc, operandTy.getElementType(),
- operand);
+ auto resultType = operand.getType();
+ if (auto complexResultType = mlir::dyn_cast<cir::ComplexType>(resultType))
+ resultType = complexResultType.getElementType();
+ return cir::ComplexImagOp::create(*this, loc, resultType, operand);
}
cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 0a78492aa9a86..e83af427bbf26 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3291,18 +3291,20 @@ def CIR_ComplexRealOp : CIR_Op<"complex.real", [Pure]> {
def CIR_ComplexImagOp : CIR_Op<"complex.imag", [Pure]> {
let summary = "Extract the imaginary part of a complex value";
let description = [{
- `cir.complex.imag` operation takes an operand of `!cir.complex` type and
- yields the imaginary part of it.
+ `cir.complex.imag` operation takes an operand of `!cir.complex`, `!cir.int`
+ or `!cir.float`. If the operand is `!cir.complex`, the imag part of it will
+ be returned, otherwise a zero value will be returned.
Example:
```mlir
- %1 = cir.complex.imag %0 : !cir.complex<!cir.float> -> !cir.float
+ %real = cir.complex.imag %complex : !cir.complex<!cir.float> -> !cir.float
+ %real = cir.complex.imag %scalar : !cir.float -> !cir.float
```
}];
let results = (outs CIR_AnyIntOrFloatType:$result);
- let arguments = (ins CIR_ComplexType:$operand);
+ let arguments = (ins CIR_AnyComplexOrIntOrFloatType:$operand);
let assemblyFormat = [{
$operand `:` qualified(type($operand)) `->` qualified(type($result))
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 500007f6f241b..768d75dc35394 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -2159,16 +2159,16 @@ mlir::Value ScalarExprEmitter::VisitRealImag(const UnaryOperator *e,
// __imag on a scalar returns zero. Emit the subexpr to ensure side
// effects are evaluated, but not the actual value.
- if (op->isGLValue())
- cgf.emitLValue(op);
- else if (!promotionTy.isNull())
- cgf.emitPromotedScalarExpr(op, promotionTy);
- else
- cgf.emitScalarExpr(op);
-
- mlir::Type valueTy =
- cgf.convertType(promotionTy.isNull() ? e->getType() : promotionTy);
- return builder.getNullValue(valueTy, loc);
+ mlir::Value operand;
+ if (op->isGLValue()) {
+ operand = cgf.emitLValue(op).getPointer();
+ operand = cir::LoadOp::create(builder, loc, operand);
+ } else if (!promotionTy.isNull()) {
+ operand = cgf.emitPromotedScalarExpr(op, promotionTy);
+ } else {
+ operand = cgf.emitScalarExpr(op);
+ }
+ return builder.createComplexImag(loc, operand);
}
/// Return the size or alignment of the type of argument of the sizeof
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 6b5cc808e9a29..5d96848f83b82 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2418,7 +2418,12 @@ OpFoldResult cir::ComplexRealOp::fold(FoldAdaptor adaptor) {
//===----------------------------------------------------------------------===//
LogicalResult cir::ComplexImagOp::verify() {
- if (getType() != getOperand().getType().getElementType()) {
+ mlir::Type operandTy = getOperand().getType();
+ if (auto complexOperandTy = mlir::dyn_cast<cir::ComplexType>(operandTy)) {
+ operandTy = complexOperandTy.getElementType();
+ }
+
+ if (getType() != operandTy) {
emitOpError() << ": result type does not match operand type";
return failure();
}
@@ -2426,6 +2431,9 @@ LogicalResult cir::ComplexImagOp::verify() {
}
OpFoldResult cir::ComplexImagOp::fold(FoldAdaptor adaptor) {
+ if (!mlir::isa<cir::ComplexType>(getOperand().getType()))
+ return nullptr;
+
if (auto complexCreateOp = getOperand().getDefiningOp<cir::ComplexCreateOp>())
return complexCreateOp.getOperand(1);
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 4bc7783175120..0f26b47450705 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -3062,8 +3062,19 @@ mlir::LogicalResult CIRToLLVMComplexImagOpLowering::matchAndRewrite(
cir::ComplexImagOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
mlir::Type resultLLVMTy = getTypeConverter()->convertType(op.getType());
- rewriter.replaceOpWithNewOp<mlir::LLVM::ExtractValueOp>(
- op, resultLLVMTy, adaptor.getOperand(), llvm::ArrayRef<std::int64_t>{1});
+ mlir::Value operand = adaptor.getOperand();
+ mlir::Location loc = op.getLoc();
+
+ if (mlir::isa<cir::ComplexType>(op.getOperand().getType())) {
+ operand = mlir::LLVM::ExtractValueOp::create(
+ rewriter, loc, resultLLVMTy, operand, llvm::ArrayRef<std::int64_t>{1});
+ } else {
+ mlir::TypedAttr zeroAttr = rewriter.getZeroAttr(resultLLVMTy);
+ operand =
+ mlir::LLVM::ConstantOp::create(rewriter, loc, resultLLVMTy, zeroAttr);
+ }
+
+ rewriter.replaceOp(op, operand);
return mlir::success();
}
diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp
index ae69b2486efd0..f5266712ab793 100644
--- a/clang/test/CIR/CodeGen/complex.cpp
+++ b/clang/test/CIR/CodeGen/complex.cpp
@@ -1160,8 +1160,9 @@ void imag_on_scalar_glvalue() {
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["a"]
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["b", init]
-// CIR: %[[CONST_ZERO:.*]] = cir.const #cir.fp<0.000000e+00> : !cir.float
-// CIR: cir.store{{.*}} %[[CONST_ZERO]], %[[B_ADDR]] : !cir.float, !cir.ptr<!cir.float>
+// CIR: %[[TMP_A:.*]] = cir.load %[[A_ADDR]] : !cir.ptr<!cir.float>, !cir.float
+// CIR: %[[A_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.float -> !cir.float
+// CIR: cir.store{{.*}} %[[A_IMAG]], %[[B_ADDR]] : !cir.float, !cir.ptr<!cir.float>
// LLVM: %[[A_ADDR:.*]] = alloca float, i64 1, align 4
// LLVM: %[[B_ADDR:.*]] = alloca float, i64 1, align 4
@@ -1205,9 +1206,10 @@ void imag_on_scalar_with_type_promotion() {
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.f16, !cir.ptr<!cir.f16>, ["a"]
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.f16, !cir.ptr<!cir.f16>, ["b", init]
-// CIR: %[[CONST_ZERO:.*]] = cir.const #cir.fp<0.000000e+00> : !cir.float
-// CIR: %[[CONST_ZERO_F16:.*]] = cir.cast floating %[[CONST_ZERO]] : !cir.float -> !cir.f16
-// CIR: cir.store{{.*}} %[[CONST_ZERO_F16]], %[[B_ADDR]] : !cir.f16, !cir.ptr<!cir.f16>
+// CIR: %[[TMP_A:.*]] = cir.load %[[A_ADDR]] : !cir.ptr<!cir.f16>, !cir.f16
+// CIR: %[[A_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.f16 -> !cir.f16
+// CIR: %[[A_IMAG_F16:.*]] = cir.cast floating %[[A_IMAG]] : !cir.f16 -> !cir.f16
+// CIR: cir.store{{.*}} %[[A_IMAG_F16]], %[[B_ADDR]] : !cir.f16, !cir.ptr<!cir.f16>
// LLVM: %[[A_ADDR:.*]] = alloca half, i64 1, align 2
// LLVM: %[[B_ADDR:.*]] = alloca half, i64 1, align 2
@@ -1225,8 +1227,8 @@ void imag_on_const_scalar() {
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["a"]
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["b", init]
// CIR: %[[CONST_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float
-// CIR: %[[CONST_ZERO:.*]] = cir.const #cir.fp<0.000000e+00> : !cir.float
-// CIR: cir.store{{.*}} %[[CONST_ZERO]], %[[B_ADDR]] : !cir.float, !cir.ptr<!cir.float>
+// CIR: %[[CONST_IMAG:.*]] = cir.complex.imag %[[CONST_ONE]] : !cir.float -> !cir.float
+// CIR: cir.store{{.*}} %[[CONST_IMAG]], %[[B_ADDR]] : !cir.float, !cir.ptr<!cir.float>
// LLVM: %[[A_ADDR:.*]] = alloca float, i64 1, align 4
// LLVM: %[[B_ADDR:.*]] = alloca float, i64 1, align 4
|
8856005
to
b6e720d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after nit
533adea
to
c93c243
Compare
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/52/builds/11662 Here is the relevant piece of the build log for the reference
|
Update cir::ComplexImagOp to make it visible on scalars Issue llvm#160568
Update cir::ComplexImagOp to make it visible on scalars
Issue #160568