diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerCall.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerCall.cpp index c314b6f3977c..1f59e5094d18 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerCall.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerCall.cpp @@ -47,8 +47,13 @@ arrangeFreeFunctionLikeCall(LowerTypes <, LowerModule &LM, cir_cconv_assert(!::cir::MissingFeatures::chainCall() && !chainCall && "NYI"); FnInfoOpts opts = chainCall ? FnInfoOpts::IsChainCall : FnInfoOpts::None; - return LT.arrangeLLVMFunctionInfo(fnType.getReturnType(), opts, - fnType.getInputs(), required); + + SmallVector argTypes; + for (const auto &a : args) + argTypes.push_back(a.getType()); + + return LT.arrangeLLVMFunctionInfo(fnType.getReturnType(), opts, argTypes, + required); } /// Adds the formal parameters in FPT to the given prefix. If any parameter in diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunctionInfo.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunctionInfo.h index 394bd2b62951..8da01bc23ada 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunctionInfo.h +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunctionInfo.h @@ -49,12 +49,15 @@ class RequiredArgs { if (!prototype.isVarArg()) return All; - cir_cconv_assert_or_abort(!::cir::MissingFeatures::variadicFunctions(), - "NYI"); - return All; // FIXME(cir): Temporary workaround for the assertion above. + return RequiredArgs(prototype.getNumInputs() + additional); } bool allowsOptionalArgs() const { return NumRequired != ~0U; } + + unsigned getNumRequiredArgs() const { + assert(allowsOptionalArgs()); + return NumRequired; + } }; // Implementation detail of LowerFunctionInfo, factored out so it can be @@ -149,14 +152,9 @@ class LowerFunctionInfo final unsigned arg_size() const { return NumArgs; } - bool isVariadic() const { - cir_cconv_assert(!::cir::MissingFeatures::variadicFunctions()); - return false; - } + bool isVariadic() const { return Required.allowsOptionalArgs(); } unsigned getNumRequiredArgs() const { - if (isVariadic()) - cir_cconv_unreachable("NYI"); - return arg_size(); + return isVariadic() ? Required.getNumRequiredArgs() : arg_size(); } Type getReturnType() const { return getArgsBuffer()[0].type; } diff --git a/clang/test/CIR/CallConvLowering/x86_64/varargs.c b/clang/test/CIR/CallConvLowering/x86_64/varargs.c new file mode 100644 index 000000000000..fdc505aa6c5f --- /dev/null +++ b/clang/test/CIR/CallConvLowering/x86_64/varargs.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fclangir-call-conv-lowering -emit-cir-flat -mmlir --mlir-print-ir-after=cir-call-conv-lowering %s -o %t.cir + +int printf(const char *str, ...); + +// CHECK: cir.func {{.*@bar}} +// CHECK: %[[#V1:]] = cir.alloca !s32i, !cir.ptr, ["a", init] +// CHECK: %[[#V2:]] = cir.alloca !s32i, !cir.ptr, ["b", init] +// CHECK: cir.store %arg0, %[[#V0]] : !s32i, !cir.ptr +// CHECK: cir.store %arg1, %[[#V1]] : !s32i, !cir.ptr +// CHECK: %[[#V2:]] = cir.get_global @".str" : !cir.ptr> +// CHECK: %[[#V3:]] = cir.cast(array_to_ptrdecay, %[[#V2]] : !cir.ptr>), !cir.ptr +// CHECK: %[[#V4:]] = cir.load %[[#V1]] : !cir.ptr, !s32i +// CHECK: %[[#V5:]] = cir.load %[[#V2]] : !cir.ptr, !s32i +// CHECK: %[[#V6:]] = cir.call @printf(%[[#V3]], %[[#V4]], %[[#V5]]) : (!cir.ptr, !s32i, !s32i) -> !s32i +void bar(int a, int b) { + printf("%d %d\n", a, b); +}