This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd30dfa86760c: [clang][patch] Add support for option 
-fextend-arguments={32,64}: widen integer… (authored by mibintc).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101640/new/

https://reviews.llvm.org/D101640

Files:
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/LangOptions.h
  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
  clang/test/Driver/fextend-args.c

Index: clang/test/Driver/fextend-args.c
===================================================================
--- /dev/null
+++ clang/test/Driver/fextend-args.c
@@ -0,0 +1,17 @@
+// Options for intel arch
+// RUN: %clang -### -target x86_64-apple-darwin -fextend-arguments=32 %s 2>&1 \
+// RUN: | FileCheck --implicit-check-not "-fextend-arguments=32"  %s
+// RUN: %clang -### -target x86_64-apple-darwin -fextend-arguments=64 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-64 %s
+
+// Unsupported target
+// RUN: not %clang -target aarch64-unknown-windows-msvc -fextend-arguments=32 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=UNSUPPORTED-TARGET %s
+
+// Invalid option value
+// RUN: not %clang -target x86_64-apple-darwin -fextend-arguments=0 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=INVALID-VALUE %s
+
+// CHECK-64: "-cc1" {{.*}}"-fextend-arguments=64"
+// UNSUPPORTED-TARGET: error: unsupported option
+// INVALID-VALUE: error: invalid argument '0' to -fextend-arguments
Index: clang/test/CodeGen/extend-arg-64.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/extend-arg-64.c
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -DD128 -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 -DD128 -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, ...);
+void knr();
+
+unsigned int u32;
+int s32;
+unsigned short u16;
+short s16;
+unsigned char u8;
+signed char s8;
+long long ll;
+_ExtInt(23) ei23;
+float ff;
+double dd;
+#ifdef D128
+__int128 i128;
+#endif
+
+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);
+  knr(ll);
+  // CHECKEXT: load i64, i64* @ll
+  // CHECKEXT-NEXT: call void (i64, ...) bitcast {{.*}} @knr
+
+  knr(ei23);
+  // CHECKEXT: load i23, i23* @ei23
+  // CHECKEXT-NEXT: call void (i23, ...) bitcast{{.*}} @knr
+
+  knr(ff);
+  // CHECKEXT: load float
+  // CHECKEXT-NEXT: fpext float {{.*}} to double
+  // CHECKEXT-NEXT: call{{.*}} void (double, ...) bitcast{{.*}} @knr
+
+  knr(dd);
+  // CHECKEXT: load double
+  // CHECKEXT-NEXT: call{{.*}} void (double, ...) bitcast{{.*}} @knr
+
+#ifdef D128
+  knr(i128);
+  // CHECKEXT: load i128
+  // CHECKEXT: call{{.*}} void (i64, i64, ...) bitcast{{.*}} @knr
+#endif
+
+  knr(u32, s32, u16, s16, u8, s8);
+  // 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{{.*}} void (i64, i64, i64, i64, i64, i64, ...) bitcast{{.*}} @knr
+  return sum;
+}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -821,6 +821,19 @@
       E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get();
     }
   }
+  if (BTy &&
+      getLangOpts().getExtendIntArgs() ==
+          LangOptions::ExtendArgsKind::ExtendTo64 &&
+      Context.getTargetInfo().supportsExtendIntArgs() && Ty->isIntegerType() &&
+      Context.getTypeSizeInChars(BTy) <
+          Context.getTypeSizeInChars(Context.LongLongTy)) {
+    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
@@ -4903,6 +4903,20 @@
 
   RenderFloatingPointOptions(TC, D, OFastEnabled, Args, CmdArgs, JA);
 
+  if (Arg *A = Args.getLastArg(options::OPT_fextend_args_EQ)) {
+    const llvm::Triple::ArchType Arch = TC.getArch();
+    if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
+      StringRef V = A->getValue();
+      if (V == "64")
+        CmdArgs.push_back("-fextend-arguments=64");
+      else if (V != "32")
+        D.Diag(diag::err_drv_invalid_argument_to_option)
+            << A->getValue() << A->getOption().getName();
+    } else
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << A->getOption().getName() << TripleStr;
+  }
+
   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
@@ -338,6 +338,10 @@
 
   bool setFPMath(StringRef Name) override;
 
+  bool supportsExtendIntArgs() 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
@@ -1451,6 +1451,14 @@
   PosFlag<SetTrue, [CC1Option], "Require math functions to indicate errors by setting errno">,
   NegFlag<SetFalse>>,
   ShouldParseIf<!strconcat("!", open_cl.KeyPath)>;
+def fextend_args_EQ : Joined<["-"], "fextend-arguments=">, Group<f_Group>,
+  Flags<[CC1Option, NoArgumentUnused]>,
+  HelpText<"Controls how scalar integer arguments are extended in calls "
+           "to unprototyped and varargs functions">,
+  Values<"32,64">,
+  NormalizedValues<["ExtendTo32", "ExtendTo64"]>,
+  NormalizedValuesScope<"LangOptions::ExtendArgsKind">,
+  MarshallingInfoEnum<LangOpts<"ExtendIntArgs">,"ExtendTo32">;
 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
@@ -1415,6 +1415,9 @@
   bool isBigEndian() const { return BigEndian; }
   bool isLittleEndian() const { return !BigEndian; }
 
+  /// Whether the option -fextend-arguments={32,64} is supported on the target.
+  virtual bool supportsExtendIntArgs() 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.h
===================================================================
--- clang/include/clang/Basic/LangOptions.h
+++ clang/include/clang/Basic/LangOptions.h
@@ -267,6 +267,13 @@
     Single
   };
 
+  enum class ExtendArgsKind {
+    /// Integer arguments are sign or zero extended to 32/64 bits
+    /// during default argument promotions.
+    ExtendTo32,
+    ExtendTo64
+  };
+
 public:
   /// The used language standard.
   LangStandard::Kind LangStd;
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -415,6 +415,10 @@
 
 LANGOPT(ArmSveVectorBits, 32, 0, "SVE vector size in bits")
 
+ENUM_LANGOPT(ExtendIntArgs, ExtendArgsKind, 1, ExtendArgsKind::ExtendTo32, 
+             "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

Reply via email to