[llvm] de34a94 - [X86] Add -mskip-rax-setup support to align with GCC

Phoebe Wang via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 17 19:20:40 PST 2021


Author: Phoebe Wang
Date: 2021-11-18T11:20:32+08:00
New Revision: de34a940ae72dfa6425a025538484f9505ca1d42

URL: https://github.com/llvm/llvm-project/commit/de34a940ae72dfa6425a025538484f9505ca1d42
DIFF: https://github.com/llvm/llvm-project/commit/de34a940ae72dfa6425a025538484f9505ca1d42.diff

LOG: [X86] Add -mskip-rax-setup support to align with GCC

AMD64 ABI mandates caller to specify the number of used SSE registers
when passing variable arguments.
GCC also provides option -mskip-rax-setup to skip the setup of rax when
SSE is disabled. This helps to reduce the code size, see pr23258.

Reviewed By: nickdesaulniers

Differential Revision: https://reviews.llvm.org/D112413

Added: 
    clang/test/CodeGen/pr23258.c
    llvm/test/CodeGen/X86/pr23258.ll

Modified: 
    clang/include/clang/Basic/CodeGenOptions.def
    clang/include/clang/Driver/Options.td
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/test/Driver/x86_features.c
    llvm/lib/Target/X86/X86ISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 0897e86611424..94b3003a9c33c 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -456,6 +456,9 @@ CODEGENOPT(EmitIEEENaNCompliantInsts, 1, 1)
 ENUM_CODEGENOPT(SwiftAsyncFramePointer, SwiftAsyncFramePointerKind, 2,
                 SwiftAsyncFramePointerKind::Always)
 
+/// Whether to skip RAX setup when passing variable arguments (x86 only).
+CODEGENOPT(SkipRaxSetup, 1, 0)
+
 #undef CODEGENOPT
 #undef ENUM_CODEGENOPT
 #undef VALUE_CODEGENOPT

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 743e190620584..7730c0b982bb6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3196,6 +3196,10 @@ def mno_outline : Flag<["-"], "mno-outline">, Group<f_clang_Group>, Flags<[CC1Op
     HelpText<"Disable function outlining (AArch64 only)">;
 def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group<m_Group>,
   HelpText<"Do not set the default structure layout to be compatible with the Microsoft compiler standard">;
+def mskip_rax_setup : Flag<["-"], "mskip-rax-setup">, Group<m_Group>, Flags<[CC1Option]>,
+  HelpText<"Skip setting up RAX register when passing variable arguments (x86 only)">,
+  MarshallingInfoFlag<CodeGenOpts<"SkipRaxSetup">>;
+def mno_skip_rax_setup : Flag<["-"], "mno-skip-rax-setup">, Group<m_Group>, Flags<[CC1Option]>;
 def mstackrealign : Flag<["-"], "mstackrealign">, Group<m_Group>, Flags<[CC1Option]>,
   HelpText<"Force realign the stack at entry to every function">,
   MarshallingInfoFlag<CodeGenOpts<"StackRealignment">>;

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 1f094ed727242..59f3e02705713 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -840,6 +840,8 @@ void CodeGenModule::Release() {
         getCodeGenOpts().StackProtectorGuardOffset);
   if (getCodeGenOpts().StackAlignment)
     getModule().setOverrideStackAlignment(getCodeGenOpts().StackAlignment);
+  if (getCodeGenOpts().SkipRaxSetup)
+    getModule().addModuleFlag(llvm::Module::Override, "SkipRaxSetup", 1);
 
   getTargetCodeGenInfo().emitTargetMetadata(*this, MangledDeclNames);
 

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 88e1764a9dadd..e5476e07a5ccf 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2210,6 +2210,11 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
     CmdArgs.push_back("-x86-asm-syntax=intel");
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_mskip_rax_setup,
+                               options::OPT_mno_skip_rax_setup))
+    if (A->getOption().matches(options::OPT_mskip_rax_setup))
+      CmdArgs.push_back(Args.MakeArgString("-mskip-rax-setup"));
+
   // Set flags to support MCU ABI.
   if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) {
     CmdArgs.push_back("-mfloat-abi");

diff  --git a/clang/test/CodeGen/pr23258.c b/clang/test/CodeGen/pr23258.c
new file mode 100644
index 0000000000000..f67f48ac9c3e6
--- /dev/null
+++ b/clang/test/CodeGen/pr23258.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=NO-SKIP
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -mskip-rax-setup -emit-llvm %s -o - | FileCheck %s -check-prefix=SKIP
+
+void f() {}
+
+// SKIP: !"SkipRaxSetup", i32 1}
+// NO-SKIP-NOT: "SkipRaxSetup"

diff  --git a/clang/test/Driver/x86_features.c b/clang/test/Driver/x86_features.c
index e5ca704fdcd33..8d7f2c73d6f87 100644
--- a/clang/test/Driver/x86_features.c
+++ b/clang/test/Driver/x86_features.c
@@ -5,3 +5,9 @@
 // Test that we don't produce an error with -mieee-fp.
 // RUN: %clang -### %s -mieee-fp -S 2>&1 | FileCheck --check-prefix=IEEE %s
 // IEEE-NOT: error: unknown argument
+
+// RUN: %clang -### %s -mskip-rax-setup -S 2>&1 | FileCheck --check-prefix=SRS %s
+// SRS: "-mskip-rax-setup"
+
+// RUN: %clang -### %s -mno-skip-rax-setup -S 2>&1 | FileCheck --check-prefix=NO-SRS %s
+// NO-SRS-NOT: "-mskip-rax-setup"

diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 828b4262b7476..09e51977e095d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -4415,7 +4415,8 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
     }
   }
 
-  if (Is64Bit && isVarArg && !IsWin64 && !IsMustTail) {
+  if (Is64Bit && isVarArg && !IsWin64 && !IsMustTail &&
+      (Subtarget.hasSSE1() || !M->getModuleFlag("SkipRaxSetup"))) {
     // From AMD64 ABI document:
     // For calls that may call functions that use varargs or stdargs
     // (prototype-less calls or calls to functions containing ellipsis (...) in

diff  --git a/llvm/test/CodeGen/X86/pr23258.ll b/llvm/test/CodeGen/X86/pr23258.ll
new file mode 100644
index 0000000000000..f777be706962f
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr23258.ll
@@ -0,0 +1,72 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=HAS-RAX
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+sse | FileCheck %s --check-prefix=HAS-RAX
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=-sse | FileCheck %s --check-prefix=NO-RAX
+
+define void @foo() {
+; HAS-RAX-LABEL: foo:
+; HAS-RAX:       # %bb.0:
+; HAS-RAX-NEXT:    movl $1, %edi
+; HAS-RAX-NEXT:    xorl %eax, %eax
+; HAS-RAX-NEXT:    jmp bar at PLT # TAILCALL
+;
+; NO-RAX-LABEL: foo:
+; NO-RAX:       # %bb.0:
+; NO-RAX-NEXT:    movl $1, %edi
+; NO-RAX-NEXT:    jmp bar at PLT # TAILCALL
+  tail call void (i32, ...) @bar(i32 1)
+  ret void
+}
+
+define void @bar(i32, ...) nounwind {
+; HAS-RAX-LABEL: bar:
+; HAS-RAX:       # %bb.0:
+; HAS-RAX-NEXT:    subq $56, %rsp
+; HAS-RAX-NEXT:    movq %rsi, -{{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:    movq %rdx, -{{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:    movq %rcx, -{{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:    movq %r8, -{{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:    movq %r9, -{{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:    testb %al, %al
+; HAS-RAX-NEXT:    je .LBB1_2
+; HAS-RAX-NEXT:  # %bb.1:
+; HAS-RAX-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:    movaps %xmm1, -{{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:    movaps %xmm2, -{{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:    movaps %xmm3, -{{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:    movaps %xmm4, -{{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:    movaps %xmm5, (%rsp)
+; HAS-RAX-NEXT:    movaps %xmm6, {{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:    movaps %xmm7, {{[0-9]+}}(%rsp)
+; HAS-RAX-NEXT:  .LBB1_2:
+; HAS-RAX-NEXT:    leaq {{[0-9]+}}(%rsp), %rax
+; HAS-RAX-NEXT:    movq %rax, 8
+; HAS-RAX-NEXT:    leaq -{{[0-9]+}}(%rsp), %rax
+; HAS-RAX-NEXT:    movq %rax, 16
+; HAS-RAX-NEXT:    movl $8, 0
+; HAS-RAX-NEXT:    movl $48, 4
+; HAS-RAX-NEXT:    addq $56, %rsp
+; HAS-RAX-NEXT:    retq
+;
+; NO-RAX-LABEL: bar:
+; NO-RAX:       # %bb.0:
+; NO-RAX-NEXT:    movq %rsi, -{{[0-9]+}}(%rsp)
+; NO-RAX-NEXT:    movq %rdx, -{{[0-9]+}}(%rsp)
+; NO-RAX-NEXT:    movq %rcx, -{{[0-9]+}}(%rsp)
+; NO-RAX-NEXT:    movq %r8, -{{[0-9]+}}(%rsp)
+; NO-RAX-NEXT:    movq %r9, -{{[0-9]+}}(%rsp)
+; NO-RAX-NEXT:    leaq {{[0-9]+}}(%rsp), %rax
+; NO-RAX-NEXT:    movq %rax, 8
+; NO-RAX-NEXT:    leaq -{{[0-9]+}}(%rsp), %rax
+; NO-RAX-NEXT:    movq %rax, 16
+; NO-RAX-NEXT:    movl $8, 0
+; NO-RAX-NEXT:    movl $48, 4
+; NO-RAX-NEXT:    retq
+  call void @llvm.va_start(i8* null)
+  ret void
+}
+
+declare void @llvm.va_start(i8*)
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 4, !"SkipRaxSetup", i32 1}


        


More information about the llvm-commits mailing list