Skip to content

Commit 8fc31d0

Browse files
committed
[CIR] Upstream ComplexImagPtrOp for ComplexType
1 parent fee27b3 commit 8fc31d0

File tree

7 files changed

+110
-8
lines changed

7 files changed

+110
-8
lines changed

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2642,6 +2642,36 @@ def ComplexRealPtrOp : CIR_Op<"complex.real_ptr", [Pure]> {
26422642
let hasVerifier = 1;
26432643
}
26442644

2645+
//===----------------------------------------------------------------------===//
2646+
// ComplexImagPtrOp
2647+
//===----------------------------------------------------------------------===//
2648+
2649+
def ComplexImagPtrOp : CIR_Op<"complex.imag_ptr", [Pure]> {
2650+
let summary = "Derive a pointer to the imaginary part of a complex value";
2651+
let description = [{
2652+
`cir.complex.imag_ptr` operation takes a pointer operand that points to a
2653+
complex value of type `!cir.complex` and yields a pointer to the imaginary
2654+
part of the operand.
2655+
2656+
Example:
2657+
2658+
```mlir
2659+
%1 = cir.complex.imag_ptr %0 : !cir.ptr<!cir.complex<!cir.double>>
2660+
-> !cir.ptr<!cir.double>
2661+
```
2662+
}];
2663+
2664+
let results = (outs CIR_PtrToIntOrFloatType:$result);
2665+
let arguments = (ins CIR_PtrToComplexType:$operand);
2666+
2667+
let assemblyFormat = [{
2668+
$operand `:`
2669+
qualified(type($operand)) `->` qualified(type($result)) attr-dict
2670+
}];
2671+
2672+
let hasVerifier = 1;
2673+
}
2674+
26452675
//===----------------------------------------------------------------------===//
26462676
// ComplexAddOp
26472677
//===----------------------------------------------------------------------===//

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,21 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
378378
addr.getAlignment()};
379379
}
380380

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

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -637,11 +637,6 @@ LValue CIRGenFunction::emitUnaryOpLValue(const UnaryOperator *e) {
637637
}
638638
case UO_Real:
639639
case UO_Imag: {
640-
if (op == UO_Imag) {
641-
cgm.errorNYI(e->getSourceRange(), "UnaryOp real/imag");
642-
return LValue();
643-
}
644-
645640
LValue lv = emitLValue(e->getSubExpr());
646641
assert(lv.isSimple() && "real/imag on non-ordinary l-value");
647642

@@ -656,7 +651,10 @@ LValue CIRGenFunction::emitUnaryOpLValue(const UnaryOperator *e) {
656651
QualType exprTy = getContext().getCanonicalType(e->getSubExpr()->getType());
657652
QualType elemTy = exprTy->castAs<clang::ComplexType>()->getElementType();
658653
mlir::Location loc = getLoc(e->getExprLoc());
659-
Address component = builder.createComplexRealPtr(loc, lv.getAddress());
654+
Address component =
655+
e->getOpcode() == UO_Real
656+
? builder.createComplexRealPtr(loc, lv.getAddress())
657+
: builder.createComplexImagPtr(loc, lv.getAddress());
660658
assert(!cir::MissingFeatures::opTBAA());
661659
LValue elemLV = makeAddrLValue(component, elemTy);
662660
elemLV.getQuals().addQualifiers(lv.getQuals());

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc"
2222
#include "clang/CIR/Dialect/IR/CIROpsEnums.cpp.inc"
2323
#include "clang/CIR/MissingFeatures.h"
24+
#include "llvm/Support/LogicalResult.h"
2425

2526
#include <numeric>
2627

@@ -2108,13 +2109,29 @@ LogicalResult cir::ComplexRealPtrOp::verify() {
21082109
mlir::cast<cir::ComplexType>(operandPtrTy.getPointee());
21092110

21102111
if (resultPointeeTy != operandPointeeTy.getElementType()) {
2111-
emitOpError() << ": result type does not match operand type";
2112-
return failure();
2112+
return emitOpError() << ": result type does not match operand type";
21132113
}
21142114

21152115
return success();
21162116
}
21172117

2118+
//===----------------------------------------------------------------------===//
2119+
// ComplexImagPtrOp
2120+
//===----------------------------------------------------------------------===//
2121+
2122+
LogicalResult cir::ComplexImagPtrOp::verify() {
2123+
mlir::Type resultPointeeTy = getType().getPointee();
2124+
cir::PointerType operandPtrTy = getOperand().getType();
2125+
auto operandPointeeTy =
2126+
mlir::cast<cir::ComplexType>(operandPtrTy.getPointee());
2127+
2128+
if (resultPointeeTy != operandPointeeTy.getElementType()) {
2129+
return emitOpError()
2130+
<< "cir.complex.imag_ptr result type does not match operand type";
2131+
}
2132+
return success();
2133+
}
2134+
21182135
//===----------------------------------------------------------------------===//
21192136
// TableGen'd op method definitions
21202137
//===----------------------------------------------------------------------===//

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,7 @@ void ConvertCIRToLLVMPass::runOnOperation() {
20512051
CIRToLLVMComplexAddOpLowering,
20522052
CIRToLLVMComplexCreateOpLowering,
20532053
CIRToLLVMComplexImagOpLowering,
2054+
CIRToLLVMComplexImagPtrOpLowering,
20542055
CIRToLLVMComplexRealOpLowering,
20552056
CIRToLLVMComplexRealPtrOpLowering,
20562057
CIRToLLVMConstantOpLowering,
@@ -2527,6 +2528,23 @@ mlir::LogicalResult CIRToLLVMSetBitfieldOpLowering::matchAndRewrite(
25272528
return mlir::success();
25282529
}
25292530

2531+
mlir::LogicalResult CIRToLLVMComplexImagPtrOpLowering::matchAndRewrite(
2532+
cir::ComplexImagPtrOp op, OpAdaptor adaptor,
2533+
mlir::ConversionPatternRewriter &rewriter) const {
2534+
cir::PointerType operandTy = op.getOperand().getType();
2535+
mlir::Type resultLLVMTy = getTypeConverter()->convertType(op.getType());
2536+
mlir::Type elementLLVMTy =
2537+
getTypeConverter()->convertType(operandTy.getPointee());
2538+
2539+
mlir::LLVM::GEPArg gepIndices[2] = {{0}, {1}};
2540+
mlir::LLVM::GEPNoWrapFlags inboundsNuw =
2541+
mlir::LLVM::GEPNoWrapFlags::inbounds | mlir::LLVM::GEPNoWrapFlags::nuw;
2542+
rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(
2543+
op, resultLLVMTy, elementLLVMTy, adaptor.getOperand(), gepIndices,
2544+
inboundsNuw);
2545+
return mlir::success();
2546+
}
2547+
25302548
mlir::LogicalResult CIRToLLVMComplexRealPtrOpLowering::matchAndRewrite(
25312549
cir::ComplexRealPtrOp op, OpAdaptor adaptor,
25322550
mlir::ConversionPatternRewriter &rewriter) const {

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,16 @@ class CIRToLLVMComplexImagOpLowering
513513
mlir::ConversionPatternRewriter &) const override;
514514
};
515515

516+
class CIRToLLVMComplexImagPtrOpLowering
517+
: public mlir::OpConversionPattern<cir::ComplexImagPtrOp> {
518+
public:
519+
using mlir::OpConversionPattern<cir::ComplexImagPtrOp>::OpConversionPattern;
520+
521+
mlir::LogicalResult
522+
matchAndRewrite(cir::ComplexImagPtrOp op, OpAdaptor,
523+
mlir::ConversionPatternRewriter &) const override;
524+
};
525+
516526
class CIRToLLVMComplexRealPtrOpLowering
517527
: public mlir::OpConversionPattern<cir::ComplexRealPtrOp> {
518528
public:

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,20 @@ void foo10() {
230230
// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8
231231
// OGCG: %[[REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0
232232

233+
void foo11() {
234+
double _Complex c;
235+
double *imagPtr = &__imag__ c;
236+
}
237+
238+
// CIR: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["c"]
239+
// CIR: %[[IMAG_PTR:.*]] = cir.complex.imag_ptr %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
240+
241+
// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8
242+
// LLVM: %[[IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1
243+
244+
// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8
245+
// OGCG: %[[IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1
246+
233247
void foo12() {
234248
double _Complex c;
235249
double imag = __imag__ c;

0 commit comments

Comments
 (0)