aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenAtomic.cpp20
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp20
-rw-r--r--clang/lib/CIR/Dialect/IR/CIRDialect.cpp13
-rw-r--r--clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp15
4 files changed, 51 insertions, 17 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index e943b02..0f4d6d2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -718,10 +718,26 @@ void CIRGenFunction::emitAtomicInit(Expr *init, LValue dest) {
return;
}
- case cir::TEK_Aggregate:
- cgm.errorNYI(init->getSourceRange(), "emitAtomicInit: aggregate type");
+ case cir::TEK_Aggregate: {
+ // Fix up the destination if the initializer isn't an expression
+ // of atomic type.
+ bool zeroed = false;
+ if (!init->getType()->isAtomicType()) {
+ zeroed = atomics.emitMemSetZeroIfNecessary();
+ dest = atomics.projectValue();
+ }
+
+ // Evaluate the expression directly into the destination.
+ assert(!cir::MissingFeatures::aggValueSlotGC());
+ AggValueSlot slot = AggValueSlot::forLValue(
+ dest, AggValueSlot::IsNotDestructed, AggValueSlot::IsNotAliased,
+ AggValueSlot::DoesNotOverlap,
+ zeroed ? AggValueSlot::IsZeroed : AggValueSlot::IsNotZeroed);
+
+ emitAggExpr(init, slot);
return;
}
+ }
llvm_unreachable("bad evaluation kind");
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 500007f..768d75d 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 fba094f..cdd4e3c 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2402,9 +2402,8 @@ OpFoldResult cir::ComplexCreateOp::fold(FoldAdaptor adaptor) {
LogicalResult cir::ComplexRealOp::verify() {
mlir::Type operandTy = getOperand().getType();
- if (auto complexOperandTy = mlir::dyn_cast<cir::ComplexType>(operandTy)) {
+ if (auto complexOperandTy = mlir::dyn_cast<cir::ComplexType>(operandTy))
operandTy = complexOperandTy.getElementType();
- }
if (getType() != operandTy) {
emitOpError() << ": result type does not match operand type";
@@ -2431,14 +2430,22 @@ 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();
}
+
return success();
}
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 bfb1262..1ff8cc5 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -3061,8 +3061,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();
}