Skip to content

Commit dc824e4

Browse files
committed
[CIR] Upstream ComplexImagPtrOp for ComplexType
1 parent 80571d5 commit dc824e4

File tree

7 files changed

+108
-7
lines changed

7 files changed

+108
-7
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2414,4 +2414,33 @@ def ComplexRealPtrOp : CIR_Op<"complex.real_ptr", [Pure]> {
24142414
let hasVerifier = 1;
24152415
}
24162416

2417+
//===----------------------------------------------------------------------===//
2418+
// ComplexImagPtrOp
2419+
//===----------------------------------------------------------------------===//
2420+
2421+
def ComplexImagPtrOp : CIR_Op<"complex.imag_ptr", [Pure]> {
2422+
let summary = "Derive a pointer to the imaginary part of a complex value";
2423+
let description = [{
2424+
`cir.complex.imag_ptr` operation takes a pointer operand that points to a
2425+
complex value of type `!cir.complex` and yields a pointer to the imaginary
2426+
part of the operand.
2427+
2428+
Example:
2429+
2430+
```mlir
2431+
%1 = cir.complex.imag_ptr %0 : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
2432+
```
2433+
}];
2434+
2435+
let results = (outs CIR_PtrToIntOrFloatType:$result);
2436+
let arguments = (ins CIR_PtrToComplexType:$operand);
2437+
2438+
let assemblyFormat = [{
2439+
$operand `:`
2440+
qualified(type($operand)) `->` qualified(type($result)) attr-dict
2441+
}];
2442+
2443+
let hasVerifier = 1;
2444+
}
2445+
24172446
#endif // CLANG_CIR_DIALECT_IR_CIROPS_TD

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,20 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
379379
return Address{createRealPtr(loc, addr.getPointer()), addr.getAlignment()};
380380
}
381381

382+
/// Create a cir.complex.imag_ptr operation that derives a pointer to the
383+
/// imaginary part of the complex value pointed to by the specified pointer
384+
/// value.
385+
mlir::Value createImagPtr(mlir::Location loc, mlir::Value value) {
386+
auto srcPtrTy = mlir::cast<cir::PointerType>(value.getType());
387+
auto srcComplexTy = mlir::cast<cir::ComplexType>(srcPtrTy.getPointee());
388+
return create<cir::ComplexImagPtrOp>(
389+
loc, getPointerTo(srcComplexTy.getElementType()), value);
390+
}
391+
392+
Address createImagPtr(mlir::Location loc, Address addr) {
393+
return Address{createImagPtr(loc, addr.getPointer()), addr.getAlignment()};
394+
}
395+
382396
/// Create a cir.ptr_stride operation to get access to an array element.
383397
/// \p idx is the index of the element to access, \p shouldDecay is true if
384398
/// the result should decay to a pointer to the element type.

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -541,11 +541,6 @@ LValue CIRGenFunction::emitUnaryOpLValue(const UnaryOperator *e) {
541541
}
542542
case UO_Real:
543543
case UO_Imag: {
544-
if (op == UO_Imag) {
545-
cgm.errorNYI(e->getSourceRange(), "UnaryOp real/imag");
546-
return LValue();
547-
}
548-
549544
LValue lv = emitLValue(e->getSubExpr());
550545
assert(lv.isSimple() && "real/imag on non-ordinary l-value");
551546

@@ -560,7 +555,9 @@ LValue CIRGenFunction::emitUnaryOpLValue(const UnaryOperator *e) {
560555
QualType exprTy = getContext().getCanonicalType(e->getSubExpr()->getType());
561556
QualType elemTy = exprTy->castAs<clang::ComplexType>()->getElementType();
562557
mlir::Location loc = getLoc(e->getExprLoc());
563-
Address component = builder.createRealPtr(loc, lv.getAddress());
558+
Address component = op == UO_Real
559+
? builder.createRealPtr(loc, lv.getAddress())
560+
: builder.createImagPtr(loc, lv.getAddress());
564561
LValue elemLV = makeAddrLValue(component, elemTy);
565562
elemLV.getQuals().addQualifiers(lv.getQuals());
566563
return elemLV;

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1794,6 +1794,25 @@ LogicalResult cir::ComplexRealPtrOp::verify() {
17941794
return success();
17951795
}
17961796

1797+
//===----------------------------------------------------------------------===//
1798+
// ComplexImagPtrOp
1799+
//===----------------------------------------------------------------------===//
1800+
1801+
LogicalResult cir::ComplexImagPtrOp::verify() {
1802+
mlir::Type resultPointeeTy = getType().getPointee();
1803+
cir::PointerType operandPtrTy = getOperand().getType();
1804+
auto operandPointeeTy =
1805+
mlir::cast<cir::ComplexType>(operandPtrTy.getPointee());
1806+
1807+
if (resultPointeeTy != operandPointeeTy.getElementType()) {
1808+
emitOpError()
1809+
<< "cir.complex.imag_ptr result type does not match operand type";
1810+
return failure();
1811+
}
1812+
1813+
return success();
1814+
}
1815+
17971816
//===----------------------------------------------------------------------===//
17981817
// TableGen'd op method definitions
17991818
//===----------------------------------------------------------------------===//

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1837,7 +1837,8 @@ void ConvertCIRToLLVMPass::runOnOperation() {
18371837
CIRToLLVMVecShuffleDynamicOpLowering,
18381838
CIRToLLVMVecTernaryOpLowering,
18391839
CIRToLLVMComplexCreateOpLowering,
1840-
CIRToLLVMComplexRealPtrOpLowering
1840+
CIRToLLVMComplexRealPtrOpLowering,
1841+
CIRToLLVMComplexImagPtrOpLowering
18411842
// clang-format on
18421843
>(converter, patterns.getContext());
18431844

@@ -2158,6 +2159,23 @@ mlir::LogicalResult CIRToLLVMComplexRealPtrOpLowering::matchAndRewrite(
21582159
return mlir::success();
21592160
}
21602161

2162+
mlir::LogicalResult CIRToLLVMComplexImagPtrOpLowering::matchAndRewrite(
2163+
cir::ComplexImagPtrOp op, OpAdaptor adaptor,
2164+
mlir::ConversionPatternRewriter &rewriter) const {
2165+
cir::PointerType operandTy = op.getOperand().getType();
2166+
mlir::Type resultLLVMTy = getTypeConverter()->convertType(op.getType());
2167+
mlir::Type elementLLVMTy =
2168+
getTypeConverter()->convertType(operandTy.getPointee());
2169+
2170+
mlir::LLVM::GEPArg gepIndices[2] = {{0}, {1}};
2171+
mlir::LLVM::GEPNoWrapFlags inboundsNuw =
2172+
mlir::LLVM::GEPNoWrapFlags::inbounds | mlir::LLVM::GEPNoWrapFlags::nuw;
2173+
rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(
2174+
op, resultLLVMTy, elementLLVMTy, adaptor.getOperand(), gepIndices,
2175+
inboundsNuw);
2176+
return mlir::success();
2177+
}
2178+
21612179
std::unique_ptr<mlir::Pass> createConvertCIRToLLVMPass() {
21622180
return std::make_unique<ConvertCIRToLLVMPass>();
21632181
}

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,16 @@ class CIRToLLVMComplexRealPtrOpLowering
428428
mlir::ConversionPatternRewriter &) const override;
429429
};
430430

431+
class CIRToLLVMComplexImagPtrOpLowering
432+
: public mlir::OpConversionPattern<cir::ComplexImagPtrOp> {
433+
public:
434+
using mlir::OpConversionPattern<cir::ComplexImagPtrOp>::OpConversionPattern;
435+
436+
mlir::LogicalResult
437+
matchAndRewrite(cir::ComplexImagPtrOp op, OpAdaptor,
438+
mlir::ConversionPatternRewriter &) const override;
439+
};
440+
431441
} // namespace direct
432442
} // namespace cir
433443

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,17 @@ void foo10() {
189189

190190
// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8
191191
// OGCG: %[[REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0
192+
193+
void foo11() {
194+
double _Complex c;
195+
double *imagPtr = &__imag__ c;
196+
}
197+
198+
// CIR: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["c"]
199+
// CIR: %[[IMAG_PTR:.*]] = cir.complex.imag_ptr %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
200+
201+
// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8
202+
// LLVM: %[[IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1
203+
204+
// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8
205+
// OGCG: %[[IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1

0 commit comments

Comments
 (0)