https://github.com/kaviya2510 updated 
https://github.com/llvm/llvm-project/pull/216700

>From be57380889d5076266cf902b9a614f1acd73bf59 Mon Sep 17 00:00:00 2001
From: Kaviya Rajendiran <[email protected]>
Date: Mon, 17 Aug 2026 16:52:45 +0530
Subject: [PATCH 1/2] [Flang][Driver]Implemented support for option
 -momit-leaf-frame-pointer/-mno-omit-leaf-frame-pointer in flang

---
 clang/include/clang/Options/Options.td        | 13 +++++--
 flang/lib/Frontend/FrontendActions.cpp        |  3 ++
 .../test/Driver/frame-pointer-forwarding.f90  | 16 ++++++++
 .../Integration/omit-leaf-frame-pointer.f90   | 39 +++++++++++++++++++
 4 files changed, 68 insertions(+), 3 deletions(-)
 create mode 100644 flang/test/Integration/omit-leaf-frame-pointer.f90

diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index adc4224dd561c..399c84c9d8359 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -6233,9 +6233,16 @@ defm zos_ppa1_name : BoolMOption<"zos-ppa1-name",
   BothFlags<[TargetSpecific], [ClangOption, CC1Option]>>;
 
 def mno_warn_nonportable_cfstrings : Flag<["-"], 
"mno-warn-nonportable-cfstrings">, Group<m_Group>;
-def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, 
Group<m_Group>;
-def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, 
Group<m_Group>,
-  HelpText<"Omit frame pointer setup for leaf functions">;
+def mno_omit_leaf_frame_pointer
+    : Flag<["-"], "mno-omit-leaf-frame-pointer">,
+      Group<m_Group>,
+      Visibility<[ClangOption, FlangOption]>,
+      HelpText<"Keep the frame pointer in leaf functions">;
+def momit_leaf_frame_pointer
+    : Flag<["-"], "momit-leaf-frame-pointer">,
+      Group<m_Group>,
+      Visibility<[ClangOption, FlangOption]>,
+      HelpText<"Omit frame pointer setup for leaf functions">;
 def mno_reserve_frame_pointer_reg : Flag<["-"], 
"mno-reserve-frame-pointer-reg">, Group<m_Group>;
 def mreserve_frame_pointer_reg : Flag<["-"], "mreserve-frame-pointer-reg">, 
Group<m_Group>,
   HelpText<"Reserve the frame pointer register even if the function doesn't 
have a frame">;
diff --git a/flang/lib/Frontend/FrontendActions.cpp 
b/flang/lib/Frontend/FrontendActions.cpp
index 7ecda651027e2..6bc8880ca759e 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -827,6 +827,9 @@ void CodeGenAction::generateLLVMIR() {
           static_cast<llvm::PIELevel::Level>(opts.PICLevel));
   }
 
+  if (opts.getFramePointer() != llvm::FramePointerKind::None)
+    llvmModule->setFramePointer(opts.getFramePointer());
+
   const TargetOptions &targetOpts = ci.getInvocation().getTargetOpts();
   const llvm::Triple triple(targetOpts.triple);
 
diff --git a/flang/test/Driver/frame-pointer-forwarding.f90 
b/flang/test/Driver/frame-pointer-forwarding.f90
index 7e97c98d899f1..68ed84d0a35f3 100644
--- a/flang/test/Driver/frame-pointer-forwarding.f90
+++ b/flang/test/Driver/frame-pointer-forwarding.f90
@@ -10,3 +10,19 @@
 
 ! RUN: %flang -fno-omit-frame-pointer --target=x86-none-none -fsyntax-only 
-### %s -o %t 2>&1  | FileCheck %s --check-prefix=CHECK-ALLFP
 ! CHECK-ALLFP: "-fc1"{{.*}}"-mframe-pointer=all"
+
+! RUN: %flang -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer 
--target=aarch64-none-none -fsyntax-only -### %s -o %t 2>&1  | FileCheck %s 
--check-prefix=CHECK-FRAME-POINTER-ALL
+! CHECK-FRAME-POINTER-ALL: "-fc1"{{.*}}"-mframe-pointer=all"
+
+! RUN: %flang -fno-omit-frame-pointer -momit-leaf-frame-pointer 
--target=x86_64-unknown-linux-gnu -fsyntax-only -### %s -o %t 2>&1  | FileCheck 
%s --check-prefix=CHECK-X86-NONLEAF
+! CHECK-X86-NONLEAF: "-fc1"{{.*}}"-mframe-pointer=non-leaf-no-reserve"
+
+! RUN: %flang -fno-omit-frame-pointer -momit-leaf-frame-pointer 
-mno-omit-leaf-frame-pointer --target=x86_64-unknown-linux-gnu -fsyntax-only 
-### %s -o %t 2>&1  | FileCheck %s --check-prefix=CHECK-LAST-WINS
+! CHECK-LAST-WINS: "-fc1"{{.*}}"-mframe-pointer=all"
+
+! Without -fno-omit-frame-pointer the leaf option is silently allowed but has 
no effect, matching Clang's behavior.
+! RUN: %flang -momit-leaf-frame-pointer --target=x86_64-unknown-linux-gnu -O2 
-fsyntax-only -### %s -o %t 2>&1  | FileCheck %s --check-prefix=CHECK-LEAF-ONLY
+! CHECK-LEAF-ONLY: "-fc1"{{.*}}"-mframe-pointer=none"
+
+subroutine test
+end subroutine test
diff --git a/flang/test/Integration/omit-leaf-frame-pointer.f90 
b/flang/test/Integration/omit-leaf-frame-pointer.f90
new file mode 100644
index 0000000000000..56f23e9e09f4f
--- /dev/null
+++ b/flang/test/Integration/omit-leaf-frame-pointer.f90
@@ -0,0 +1,39 @@
+! Test to check the options -momit-leaf-frame-pointer and 
-mno-omit-leaf-frame-pointer
+
+! REQUIRES: aarch64-registered-target, x86-registered-target
+
+! AArch64 differs from x86_64: useLeafFramePointerForTargetByDefault is false, 
so -fno-omit-frame-pointer alone already gives "non-leaf-no-reserve" on AArch64.
+
+! RUN: %flang --target=x86_64-unknown-linux-gnu -S -emit-llvm -o - %s | 
FileCheck %s --check-prefix=CHECK-ALL
+! RUN: %flang --target=x86_64-unknown-linux-gnu -fno-omit-frame-pointer 
-mno-omit-leaf-frame-pointer -S -emit-llvm -o - %s | FileCheck %s 
--check-prefix=CHECK-ALL
+! RUN: %flang --target=aarch64-none-none -fno-omit-frame-pointer 
-mno-omit-leaf-frame-pointer -S -emit-llvm -o - %s | FileCheck %s 
--check-prefix=CHECK-ALL
+
+! RUN: %flang --target=x86_64-unknown-linux-gnu -fno-omit-frame-pointer 
-momit-leaf-frame-pointer -S -emit-llvm -o - %s | FileCheck %s 
--check-prefix=CHECK-NONLEAF
+! RUN: %flang --target=aarch64-none-none -fno-omit-frame-pointer 
-momit-leaf-frame-pointer -S -emit-llvm -o - %s | FileCheck %s 
--check-prefix=CHECK-NONLEAF
+
+
+! CHECK-ALL: define void @_QQmain() #[[ATTR:[0-9]+]]
+! CHECK-ALL: define internal i32 @_QFPleaf(i32 %{{.*}}, i32 %{{.*}}) #[[ATTR]]
+! CHECK-ALL: attributes #[[ATTR]] = {{{.*}}"frame-pointer"="all"{{.*}}}
+! CHECK-ALL: !{{[0-9]+}} = !{i32 7, !"frame-pointer", i32 2}
+
+! CHECK-NONLEAF: define void @_QQmain() #[[ATTR:[0-9]+]]
+! CHECK-NONLEAF: define internal i32 @_QFPleaf(i32 %{{.*}}, i32 %{{.*}}) 
#[[ATTR]]
+! CHECK-NONLEAF: attributes #[[ATTR]] = 
{{{.*}}"frame-pointer"="non-leaf-no-reserve"{{.*}}}
+! CHECK-NONLEAF: !{{[0-9]+}} = !{i32 7, !"frame-pointer", i32 4}
+
+program test
+   implicit none
+   integer :: result
+   result = leaf(3, 4)
+   print *, result
+contains
+   integer function leaf(a, b)
+      implicit none
+      integer, value :: a, b
+      integer :: temp
+      temp = a + b
+      leaf = temp
+   end function leaf
+end program test
+

>From 9efe9430a80145bd258795c6fc4e798ab12c71aa Mon Sep 17 00:00:00 2001
From: Kaviya Rajendiran <[email protected]>
Date: Thu, 20 Aug 2026 11:58:38 +0530
Subject: [PATCH 2/2] [flang] Modified testcases and addressed review comments

---
 .../flang/Optimizer/Transforms/Passes.td      |  1 +
 .../test/Driver/frame-pointer-forwarding.f90  | 37 +++++++++++++-----
 .../Integration/omit-leaf-frame-pointer.f90   | 39 -------------------
 .../function-attr-frame-pointer.fir           | 20 ++++++++++
 4 files changed, 48 insertions(+), 49 deletions(-)
 delete mode 100644 flang/test/Integration/omit-leaf-frame-pointer.f90
 create mode 100644 flang/test/Transforms/function-attr-frame-pointer.fir

diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td 
b/flang/include/flang/Optimizer/Transforms/Passes.td
index 98090fefeeedc..f8a5f1b1679a0 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -501,6 +501,7 @@ def FunctionAttr : Pass<"function-attr", 
"mlir::func::FuncOp"> {
               "Set LLVM readonly attribute on INTENT(IN) by-reference "
               "function arguments, if possible">,
   ];
+  let dependentDialects = ["mlir::LLVM::LLVMDialect"];
 }
 
 def AssumedRankOpConversion : Pass<"fir-assumed-rank-op", "mlir::ModuleOp"> {
diff --git a/flang/test/Driver/frame-pointer-forwarding.f90 
b/flang/test/Driver/frame-pointer-forwarding.f90
index 68ed84d0a35f3..62c5d19d6f86d 100644
--- a/flang/test/Driver/frame-pointer-forwarding.f90
+++ b/flang/test/Driver/frame-pointer-forwarding.f90
@@ -11,18 +11,35 @@
 ! RUN: %flang -fno-omit-frame-pointer --target=x86-none-none -fsyntax-only 
-### %s -o %t 2>&1  | FileCheck %s --check-prefix=CHECK-ALLFP
 ! CHECK-ALLFP: "-fc1"{{.*}}"-mframe-pointer=all"
 
-! RUN: %flang -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer 
--target=aarch64-none-none -fsyntax-only -### %s -o %t 2>&1  | FileCheck %s 
--check-prefix=CHECK-FRAME-POINTER-ALL
-! CHECK-FRAME-POINTER-ALL: "-fc1"{{.*}}"-mframe-pointer=all"
+! // =======
 
-! RUN: %flang -fno-omit-frame-pointer -momit-leaf-frame-pointer 
--target=x86_64-unknown-linux-gnu -fsyntax-only -### %s -o %t 2>&1  | FileCheck 
%s --check-prefix=CHECK-X86-NONLEAF
-! CHECK-X86-NONLEAF: "-fc1"{{.*}}"-mframe-pointer=non-leaf-no-reserve"
+! Default behavior in x86_64-unknown-linux-gnu, -mframe-pointer=all at -O0 
level.
 
-! RUN: %flang -fno-omit-frame-pointer -momit-leaf-frame-pointer 
-mno-omit-leaf-frame-pointer --target=x86_64-unknown-linux-gnu -fsyntax-only 
-### %s -o %t 2>&1  | FileCheck %s --check-prefix=CHECK-LAST-WINS
-! CHECK-LAST-WINS: "-fc1"{{.*}}"-mframe-pointer=all"
+! RUN: %flang -O0 --target=x86_64-unknown-linux-gnu -### %s 2>&1 | FileCheck 
%s --check-prefix=CHECK-FRAME-POINTER-ALL
+! RUN: %flang -O0 -momit-leaf-frame-pointer --target=x86_64-unknown-linux-gnu 
-### %s 2>&1 | FileCheck %s --check-prefix=CHECK-FRAME-POINTER-NON-LEAF
+! RUN: %flang -O0 -mno-omit-leaf-frame-pointer 
--target=x86_64-unknown-linux-gnu -### %s 2>&1 | FileCheck %s 
--check-prefix=CHECK-FRAME-POINTER-ALL
+! RUN: %flang -O0 -fomit-frame-pointer -momit-leaf-frame-pointer 
--target=x86_64-unknown-linux-gnu -### %s 2>&1 | FileCheck %s 
--check-prefix=CHECK-FRAME-POINTER-NONE
+! RUN: %flang -fno-omit-frame-pointer -momit-leaf-frame-pointer 
-mno-omit-leaf-frame-pointer --target=x86_64-unknown-linux-gnu -### %s 2>&1 | 
FileCheck %s --check-prefix=CHECK-FRAME-POINTER-ALL
+
+! Default behavior in x86_64-unknown-linux-gnu, -mframe-pointer=none at 
-O1/-O2/-O3 level.
+! RUN: %flang --target=x86_64-unknown-linux-gnu -O2 -### %s 2>&1 | FileCheck 
%s --check-prefix=CHECK-FRAME-POINTER-NONE
+
+! With -fno-omit-frame-pointer and -mno-omit-leaf-frame-pointer, 
-mframe-pointer=all.
+! RUN: %flang -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer 
--target=x86_64-unknown-linux-gnu -O2 -### %s 2>&1 | FileCheck %s 
--check-prefix=CHECK-FRAME-POINTER-ALL
 
 ! Without -fno-omit-frame-pointer the leaf option is silently allowed but has 
no effect, matching Clang's behavior.
-! RUN: %flang -momit-leaf-frame-pointer --target=x86_64-unknown-linux-gnu -O2 
-fsyntax-only -### %s -o %t 2>&1  | FileCheck %s --check-prefix=CHECK-LEAF-ONLY
-! CHECK-LEAF-ONLY: "-fc1"{{.*}}"-mframe-pointer=none"
+! RUN: %flang -momit-leaf-frame-pointer --target=x86_64-unknown-linux-gnu -O2 
-### %s -o %t 2>&1  | FileCheck %s --check-prefix=CHECK-FRAME-POINTER-NONE
+! RUN: %flang -fno-omit-frame-pointer --target=x86_64-unknown-linux-gnu -O2 
-### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-FRAME-POINTER-ALL
+
+! RUN: %flang -fno-omit-frame-pointer -momit-leaf-frame-pointer 
--target=x86_64-unknown-linux-gnu -O2 -### %s 2>&1 | FileCheck %s 
--check-prefix=CHECK-FRAME-POINTER-NON-LEAF
+
+! Default behavior in aarch64-none-none, -mframe-pointer=non-leaf-no-reserve.
+! RUN: %flang -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer 
--target=aarch64-none-none -### %s 2>&1 | FileCheck %s 
--check-prefix=CHECK-FRAME-POINTER-ALL
+
+! CHECK-FRAME-POINTER-ALL: "-fc1"
+! CHECK-FRAME-POINTER-ALL-SAME: "-mframe-pointer=all"
+! CHECK-FRAME-POINTER-NON-LEAF: "-fc1"
+! CHECK-FRAME-POINTER-NON-LEAF-SAME: "-mframe-pointer=non-leaf-no-reserve"
+! CHECK-FRAME-POINTER-NONE: "-fc1"
+! CHECK-FRAME-POINTER-NONE-SAME: "-mframe-pointer=none"
 
-subroutine test
-end subroutine test
diff --git a/flang/test/Integration/omit-leaf-frame-pointer.f90 
b/flang/test/Integration/omit-leaf-frame-pointer.f90
deleted file mode 100644
index 56f23e9e09f4f..0000000000000
--- a/flang/test/Integration/omit-leaf-frame-pointer.f90
+++ /dev/null
@@ -1,39 +0,0 @@
-! Test to check the options -momit-leaf-frame-pointer and 
-mno-omit-leaf-frame-pointer
-
-! REQUIRES: aarch64-registered-target, x86-registered-target
-
-! AArch64 differs from x86_64: useLeafFramePointerForTargetByDefault is false, 
so -fno-omit-frame-pointer alone already gives "non-leaf-no-reserve" on AArch64.
-
-! RUN: %flang --target=x86_64-unknown-linux-gnu -S -emit-llvm -o - %s | 
FileCheck %s --check-prefix=CHECK-ALL
-! RUN: %flang --target=x86_64-unknown-linux-gnu -fno-omit-frame-pointer 
-mno-omit-leaf-frame-pointer -S -emit-llvm -o - %s | FileCheck %s 
--check-prefix=CHECK-ALL
-! RUN: %flang --target=aarch64-none-none -fno-omit-frame-pointer 
-mno-omit-leaf-frame-pointer -S -emit-llvm -o - %s | FileCheck %s 
--check-prefix=CHECK-ALL
-
-! RUN: %flang --target=x86_64-unknown-linux-gnu -fno-omit-frame-pointer 
-momit-leaf-frame-pointer -S -emit-llvm -o - %s | FileCheck %s 
--check-prefix=CHECK-NONLEAF
-! RUN: %flang --target=aarch64-none-none -fno-omit-frame-pointer 
-momit-leaf-frame-pointer -S -emit-llvm -o - %s | FileCheck %s 
--check-prefix=CHECK-NONLEAF
-
-
-! CHECK-ALL: define void @_QQmain() #[[ATTR:[0-9]+]]
-! CHECK-ALL: define internal i32 @_QFPleaf(i32 %{{.*}}, i32 %{{.*}}) #[[ATTR]]
-! CHECK-ALL: attributes #[[ATTR]] = {{{.*}}"frame-pointer"="all"{{.*}}}
-! CHECK-ALL: !{{[0-9]+}} = !{i32 7, !"frame-pointer", i32 2}
-
-! CHECK-NONLEAF: define void @_QQmain() #[[ATTR:[0-9]+]]
-! CHECK-NONLEAF: define internal i32 @_QFPleaf(i32 %{{.*}}, i32 %{{.*}}) 
#[[ATTR]]
-! CHECK-NONLEAF: attributes #[[ATTR]] = 
{{{.*}}"frame-pointer"="non-leaf-no-reserve"{{.*}}}
-! CHECK-NONLEAF: !{{[0-9]+}} = !{i32 7, !"frame-pointer", i32 4}
-
-program test
-   implicit none
-   integer :: result
-   result = leaf(3, 4)
-   print *, result
-contains
-   integer function leaf(a, b)
-      implicit none
-      integer, value :: a, b
-      integer :: temp
-      temp = a + b
-      leaf = temp
-   end function leaf
-end program test
-
diff --git a/flang/test/Transforms/function-attr-frame-pointer.fir 
b/flang/test/Transforms/function-attr-frame-pointer.fir
new file mode 100644
index 0000000000000..b9c0288977cd2
--- /dev/null
+++ b/flang/test/Transforms/function-attr-frame-pointer.fir
@@ -0,0 +1,20 @@
+// RUN: fir-opt --function-attr="frame-pointer=All" %s | FileCheck %s 
--check-prefix=ALL
+// RUN: fir-opt --function-attr="frame-pointer=NonLeaf" %s | FileCheck %s 
--check-prefix=NONLEAF
+// RUN: fir-opt --function-attr="frame-pointer=NonLeafNoReserve" %s | 
FileCheck %s --check-prefix=NONLEAFNORESERVE
+// RUN: fir-opt --function-attr="frame-pointer=None" %s | FileCheck %s 
--check-prefix=NONE
+
+func.func @_QPtest() {
+  return
+}
+
+// ALL-LABEL: func.func @_QPtest()
+// ALL-SAME: llvm.frame_pointer = #llvm.framePointerKind<all>
+
+// NONLEAF-LABEL: func.func @_QPtest()
+// NONLEAF-SAME: llvm.frame_pointer = #llvm.framePointerKind<"non-leaf">
+
+// NONLEAFNORESERVE-LABEL: func.func @_QPtest()
+// NONLEAFNORESERVE-SAME: llvm.frame_pointer = 
#llvm.framePointerKind<"non-leaf-no-reserve">
+
+// NONE-LABEL: func.func @_QPtest()
+// NONE-NOT: llvm.frame_pointer

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to