Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions clang/lib/CIR/CodeGen/CIRGenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,9 @@ void CIRGenModule::constructAttributeList(
// TODO(cir): add alloc size attr.
}

if (TargetDecl->hasAttr<DeviceKernelAttr>() && DeviceKernelAttr::isOpenCLSpelling(TargetDecl->getAttr<DeviceKernelAttr>())) {
if (TargetDecl->hasAttr<DeviceKernelAttr>() &&
DeviceKernelAttr::isOpenCLSpelling(
TargetDecl->getAttr<DeviceKernelAttr>())) {
auto cirKernelAttr = cir::OpenCLKernelAttr::get(&getMLIRContext());
funcAttrs.set(cirKernelAttr.getMnemonic(), cirKernelAttr);

Expand Down Expand Up @@ -476,7 +478,7 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &CallInfo,
I != E; ++I, ++type_it, ++ArgNo) {

mlir::Type argType = convertType(*type_it);
if (!mlir::isa<cir::RecordType>(argType)) {
if (!mlir::isa<cir::RecordType, cir::ComplexType>(argType)) {
mlir::Value V;
assert(!I->isAggregate() && "Aggregate NYI");
V = I->getKnownRValue().getScalarVal();
Expand All @@ -496,16 +498,16 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &CallInfo,
// FIXME: Avoid the conversion through memory if possible.
Address Src = Address::invalid();
if (!I->isAggregate()) {
llvm_unreachable("NYI");
Src = CreateMemTemp(I->Ty, loc, "coerce");
I->copyInto(*this, Src, loc);
} else {
Src = I->hasLValue() ? I->getKnownLValue().getAddress()
: I->getKnownRValue().getAggregateAddress();
}

// Fast-isel and the optimizer generally like scalar values better than
// FCAs, so we flatten them if this is safe to do for this argument.
auto STy = cast<cir::RecordType>(argType);
auto SrcTy = Src.getElementType();
auto srcTy = Src.getElementType();
// FIXME(cir): get proper location for each argument.
auto argLoc = loc;

Expand All @@ -519,13 +521,13 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &CallInfo,
// uint64_t SrcSize = CGM.getDataLayout().getTypeAllocSize(SrcTy);
// uint64_t DstSize = CGM.getDataLayout().getTypeAllocSize(STy);
// if (SrcSize < DstSize) {
if (SrcTy != STy)
if (srcTy != argType)
llvm_unreachable("NYI");
else {
// FIXME(cir): this currently only runs when the types are different,
// but should be when alloc sizes are different, fix this as soon as
// datalayout gets introduced.
Src = builder.createElementBitCast(argLoc, Src, STy);
Src = builder.createElementBitCast(argLoc, Src, argType);
}

// assert(NumCIRArgs == STy.getMembers().size());
Expand Down Expand Up @@ -757,6 +759,18 @@ mlir::Value CIRGenFunction::emitRuntimeCall(mlir::Location loc,
return call->getResult(0);
}

void CallArg::copyInto(CIRGenFunction &cgf, Address addr,
mlir::Location loc) const {
LValue dst = cgf.makeAddrLValue(addr, Ty);
if (!HasLV && RV.isScalar())
llvm_unreachable("copyInto scalar value");
else if (!HasLV && RV.isComplex())
cgf.emitStoreOfComplex(loc, RV.getComplexVal(), dst, /*isInit=*/true);
else
llvm_unreachable("copyInto hasLV");
IsUsed = true;
}

void CIRGenFunction::emitCallArg(CallArgList &args, const Expr *E,
QualType type) {
// TODO: Add the DisableDebugLocationUpdates helper
Expand Down Expand Up @@ -982,7 +996,8 @@ static void appendParameterTypes(
for (unsigned I = 0, E = FPT->getNumParams(); I != E; ++I) {
prefix.push_back(FPT->getParamType(I));
if (ExtInfos[I].hasPassObjectSize())
prefix.push_back(CGT.getContext().getCanonicalType(CGT.getContext().getSizeType()));
prefix.push_back(
CGT.getContext().getCanonicalType(CGT.getContext().getSizeType()));
}

addExtParameterInfosForCall(paramInfos, FPT.getTypePtr(), PrefixSize,
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ struct CallArg {
}

bool isAggregate() const { return HasLV || RV.isAggregate(); }

void copyInto(CIRGenFunction &cgf, Address addr, mlir::Location loc) const;
};

class CallArgList : public llvm::SmallVector<CallArg, 8> {
Expand Down
47 changes: 47 additions & 0 deletions clang/test/CIR/CodeGen/complex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,50 @@ void atomic_complex_type() {
// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 1
// OGCG: store float %[[ATOMIC_TMP_REAL]], ptr %[[B_REAL_PTR]], align 4
// OGCG: store float %[[ATOMIC_TMP_IMAG]], ptr %[[B_IMAG_PTR]], align 4

void complex_type_parameter(float _Complex a) {}

// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a", init]
// CIR: cir.store %{{.*}}, %[[A_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>

// TODO(CIR): the difference between the CIR LLVM and OGCG is because the lack of calling convention lowering,
// Test will be updated when that is implemented

// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 4
// LLVM: store { float, float } %{{.*}}, ptr %[[A_ADDR]], align 4

// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4
// OGCG: store <2 x float> %a.coerce, ptr %[[A_ADDR]], align 4

void complex_type_argument() {
float _Complex a;
complex_type_parameter(a);
}

// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]
// CIR: %[[ARG_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["coerce"]
// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
// CIR: cir.store{{.*}} %[[TMP_A]], %[[ARG_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
// CIR: %[[TMP_ARG:.*]] = cir.load{{.*}} %[[ARG_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
// CIR: cir.call @_Z22complex_type_parameterCf(%[[TMP_ARG]]) : (!cir.complex<!cir.float>) -> ()

// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 4
// LLVM: %[[ARG_ADDR:.*]] = alloca { float, float }, i64 1, align 4
// LLVM: %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 4
// LLVM: store { float, float } %[[TMP_A]], ptr %[[ARG_ADDR]], align 4
// LLVM: %[[TMP_ARG:.*]] = load { float, float }, ptr %[[ARG_ADDR]], align 4
// LLVM: call void @_Z22complex_type_parameterCf({ float, float } %[[TMP_ARG]])

// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4
// OGCG: %[[ARG_ADDR:.*]] = alloca { float, float }, align 4
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 0
// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 1
// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4
// OGCG: %[[ARG_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[ARG_ADDR]], i32 0, i32 0
// OGCG: %[[ARG_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[ARG_ADDR]], i32 0, i32 1
// OGCG: store float %[[A_REAL]], ptr %[[ARG_REAL_PTR]], align 4
// OGCG: store float %[[A_IMAG]], ptr %[[ARG_IMAG_PTR]], align 4
// OGCG: %[[TMP_ARG:.*]] = load <2 x float>, ptr %[[ARG_ADDR]], align 4
// OGCG: call void @_Z22complex_type_parameterCf(<2 x float> noundef %[[TMP_ARG]])

Loading