mibintc created this revision. mibintc added reviewers: kbsmith1, erichkeane. mibintc added a project: clang-c. Herald added subscribers: dexonsmith, dang, Anastasia. mibintc requested review of this revision. Herald added a project: clang.
The Intel C++ and Fortran compilers support the option -fextend-arguments={32,64}. One of our customers has requested that this support be added clang. This option controls how scalar integral arguments are extended in calls to unprototyped and varargs functions. When we investigated the support for the ICL option, we discovered that "-fextend-arguments=32" had no effect in the generated code, so this patch proposes to support only 64 bit extension. This patch is only meaningful for targets that pass int arguments in 64 bits. For supported targets, signed int values are sign extended to 64 bits in the parameter list, and unsigned int values are zero extended to 64 bits. @kbsmith1 tells me that this option is primarily useful for porting 32-bit programs to the 64-bit environment, and although that architecture shift happened years ago, the customer is still interested in this support. It turns out that there is currently similar logic in clang support for the OpenCL option "cl_khr_fp64" which causes certain float arguments, in unprototyped context, to be expanded to float or double. Will this change be acceptable? Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D101640 Files: clang/include/clang/Basic/LangOptions.def clang/include/clang/Basic/TargetInfo.h clang/include/clang/Driver/Options.td clang/lib/Basic/Targets/X86.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Sema/SemaExpr.cpp clang/test/CodeGen/extend-arg-64.c
Index: clang/test/CodeGen/extend-arg-64.c =================================================================== --- /dev/null +++ clang/test/CodeGen/extend-arg-64.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fextend-arguments-64 \ +// RUN: %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECKEXT + +// When the option isn't selected, no effect +// RUN: %clang_cc1 -triple x86_64-apple-darwin \ +// RUN: %s -emit-llvm -o - | FileCheck %s \ +// RUN: --implicit-check-not "ext {{.*}}to i64" + +// The option isn't supported on x86, no effect +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -fextend-arguments-64 \ +// RUN: %s -emit-llvm -o - | FileCheck %s \ +// RUN: --implicit-check-not "ext {{.*}}to i64" + +// The option isn't supported on ppc, no effect +// RUN: %clang_cc1 -triple ppc64le -fextend-arguments-64 \ +// RUN: %s -emit-llvm -o - | FileCheck %s \ +// RUN: --implicit-check-not "ext {{.*}}to i64" + +int vararg(int, ...); + +unsigned int u32; +int s32; +unsigned short u16; +short s16; +unsigned char u8; +signed char s8; + +int test() { + // CHECK: define{{.*}} i32 @test{{.*}} + + // CHECKEXT: [[TAG_u32:%.*]] = load i32, i32* @u32{{.*}} + // CHECKEXT: [[CONV_u32:%.*]] = zext i32 [[TAG_u32]] to i64 + + // CHECKEXT: [[TAG_s32:%.*]] = load i32, i32* @s32 + // CHECKEXT: [[CONV_s32:%.*]] = sext i32 [[TAG_s32]] to i64 + + // CHECKEXT: [[TAG_u16:%.*]] = load i16, i16* @u16 + // CHECKEXT: [[CONV_u16:%.*]] = zext i16 [[TAG_u16]] to i64 + + // CHECKEXT: [[TAG_s16:%.*]] = load i16, i16* @s16 + // CHECKEXT: [[CONV_s16:%.*]] = sext i16 [[TAG_s16]] to i64 + + // CHECKEXT: [[TAG_u8:%.*]] = load i8, i8* @u8 + // CHECKEXT: [[CONV_u8:%.*]] = zext i8 [[TAG_u8]] to i64 + + // CHECKEXT: [[TAG_s8:%.*]] = load i8, i8* @s8 + // CHECKEXT: [[CONV_s8:%.*]] = sext i8 [[TAG_s8]] to i64 + // CHECKEXT: call{{.*}} @vararg(i32 %0, i64 [[CONV_u32]], i64 [[CONV_s32]], i64 [[CONV_u16]], i64 [[CONV_s16]], i64 [[CONV_u8]], i64 [[CONV_s8]] + + int sum = 0; + sum = vararg(sum, u32, s32, u16, s16, u8, s8); + return sum; +} Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -821,6 +821,15 @@ E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get(); } } + if (BTy && getLangOpts().ExtendArgs64 && + Context.getTargetInfo().supportsExtendArgs64() && Ty->isIntegerType()) { + E = (Ty->isUnsignedIntegerType()) + ? ImpCastExprToType(E, Context.UnsignedLongLongTy, CK_IntegralCast) + .get() + : ImpCastExprToType(E, Context.LongLongTy, CK_IntegralCast).get(); + assert(8 == Context.getTypeSizeInChars(Context.LongLongTy).getQuantity() && + "Unexpected typesize for LongLongTy"); + } // C++ performs lvalue-to-rvalue conversion as a default argument // promotion, even on class types, but note: Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -4908,6 +4908,9 @@ RenderFloatingPointOptions(TC, D, OFastEnabled, Args, CmdArgs, JA); + if (Args.getLastArg(options::OPT_fextend_args_64)) + CmdArgs.push_back("-fextend-arguments-64"); + if (Arg *A = Args.getLastArg(options::OPT_mdouble_EQ)) { if (TC.getArch() == llvm::Triple::avr) A->render(Args, CmdArgs); Index: clang/lib/Basic/Targets/X86.h =================================================================== --- clang/lib/Basic/Targets/X86.h +++ clang/lib/Basic/Targets/X86.h @@ -336,6 +336,10 @@ bool setFPMath(StringRef Name) override; + bool supportsExtendArgs64() const override { + return getTriple().getArch() != llvm::Triple::x86; + } + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { // Most of the non-ARM calling conventions are i386 conventions. switch (CC) { Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1427,6 +1427,11 @@ PosFlag<SetTrue, [CC1Option], "Require math functions to indicate errors by setting errno">, NegFlag<SetFalse>>, ShouldParseIf<!strconcat("!", open_cl.KeyPath)>; +def fextend_args_64 : Flag<["-"], "fextend-arguments-64">, Group<f_Group>, + Flags<[CC1Option, NoArgumentUnused]>, + HelpText<"Controls how scalar integer arguments are extended in calls" + " to unprototyped and varargs functions">, + MarshallingInfoFlag<LangOpts<"ExtendArgs64">>; def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>, Flags<[CoreOption]>; def fsignaling_math : Flag<["-"], "fsignaling-math">, Group<f_Group>; def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>; Index: clang/include/clang/Basic/TargetInfo.h =================================================================== --- clang/include/clang/Basic/TargetInfo.h +++ clang/include/clang/Basic/TargetInfo.h @@ -1412,6 +1412,8 @@ bool isBigEndian() const { return BigEndian; } bool isLittleEndian() const { return !BigEndian; } + virtual bool supportsExtendArgs64() const { return false; } + /// Gets the default calling convention for the given target and /// declaration context. virtual CallingConv getDefaultCallingConv() const { Index: clang/include/clang/Basic/LangOptions.def =================================================================== --- clang/include/clang/Basic/LangOptions.def +++ clang/include/clang/Basic/LangOptions.def @@ -414,6 +414,10 @@ LANGOPT(ArmSveVectorBits, 32, 0, "SVE vector size in bits") +COMPATIBLE_LANGOPT(ExtendArgs64, 1, 0, + "Controls how scalar integer arguments are extended in calls" + " to unprototyped and varargs functions") + #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits