https://github.com/keith-packard created 
https://github.com/llvm/llvm-project/pull/110928

Add support for using a thread-local variable with a specified offset for 
holding the stack guard canary value. This supports both 32- and 64- bit 
PowerPC targets.

This mirrors changes from #108942 but targeting PowerPC instead of RISCV. 
Because both of these PRs modify the same driver functions, this series is 
stack on top of the RISC-V one.


>From f91cf985d10a07af617b6098f50d023108d060a4 Mon Sep 17 00:00:00 2001
From: Keith Packard <kei...@keithp.com>
Date: Wed, 2 Oct 2024 12:37:30 -0700
Subject: [PATCH 1/9] [RISCV][ISelLowering] Use getModule() instead of
 getParent()->getParent()

This is a simple clean-up motivated by review of changes adding TLS
support for the stack canary. Using getModule() is a shorter and
clearer expression of the desired operation.

Signed-off-by: Keith Packard <kei...@keithp.com>
---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4f77bba2968988..ef1ca110c4703b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21304,7 +21304,7 @@ bool RISCVTargetLowering::preferScalarizeSplat(SDNode 
*N) const {
 }
 
 static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
-  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+  Module *M = IRB.GetInsertBlock()->getModule();
   Function *ThreadPointerFunc =
       Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
   return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),

>From bc4cde4b367b3083eba91d3e3850fda988552090 Mon Sep 17 00:00:00 2001
From: Keith Packard <kei...@keithp.com>
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 2/9] [RISCV][ISelLowering] Support -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard <kei...@keithp.com>
---
 clang/lib/Driver/ToolChains/Clang.cpp       | 28 ++++++++++++++++++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  8 ++++++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index b9987288d82d10..c9baca00ec6f3b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
     StringRef Value = A->getValue();
     if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-        !EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+        !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+        !EffectiveTriple.isRISCV())
       D.Diag(diag::err_drv_unsupported_opt_for_target)
           << A->getAsString(Args) << TripleStr;
     if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3645,28 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
           << A->getOption().getName() << Value << "sysreg global";
       return;
     }
+    if (EffectiveTriple.isRISCV()) {
+      if (Value != "tls" && Value != "global") {
+        D.Diag(diag::err_drv_invalid_value_with_suggestion)
+            << A->getOption().getName() << Value << "tls global";
+        return;
+      }
+      if (Value == "tls") {
+        if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+          D.Diag(diag::err_drv_ssp_missing_offset_argument)
+              << A->getAsString(Args);
+          return;
+        }
+      }
+    }
     A->render(Args, CmdArgs);
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) 
{
     StringRef Value = A->getValue();
     if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-        !EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+        !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+        !EffectiveTriple.isRISCV())
       D.Diag(diag::err_drv_unsupported_opt_for_target)
           << A->getAsString(Args) << TripleStr;
     int Offset;
@@ -3669,7 +3685,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
 
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
     StringRef Value = A->getValue();
-    if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+    if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+        !EffectiveTriple.isRISCV())
       D.Diag(diag::err_drv_unsupported_opt_for_target)
           << A->getAsString(Args) << TripleStr;
     if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3698,11 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
       D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
       return;
     }
+    if (EffectiveTriple.isRISCV() && Value != "tp") {
+      D.Diag(diag::err_drv_invalid_value_with_suggestion)
+          << A->getOption().getName() << Value << "tp";
+      return;
+    }
     A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index ef1ca110c4703b..a0f885695c2051 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21323,6 +21323,14 @@ Value 
*RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
   if (Subtarget.isTargetAndroid())
     return useTpOffset(IRB, -0x18);
 
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+    // Users must specify the offset explicitly
+    int Offset = M->getStackProtectorGuardOffset();
+    return useTpOffset(IRB, Offset);
+  }
+
   return TargetLowering::getIRStackGuard(IRB);
 }
 

>From 83dc53cf838256193604c77cab3fdec9a55ab763 Mon Sep 17 00:00:00 2001
From: Keith Packard <kei...@keithp.com>
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 3/9] [clang][RISCV] Add stack protector tests

Add tests ensuring that the driver correctly handles stack protector
guard options.

Signed-off-by: Keith Packard <kei...@keithp.com>
---
 clang/test/CodeGen/stack-protector-guard.c |  8 ++++++++
 clang/test/Driver/stack-protector-guard.c  | 19 +++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..4777367c94e733 100644
--- a/clang/test/CodeGen/stack-protector-guard.c
+++ b/clang/test/CodeGen/stack-protector-guard.c
@@ -9,6 +9,9 @@
 // RUN: %clang_cc1 -mstack-protector-guard=sysreg -triple aarch64-linux-gnu \
 // RUN:   -mstack-protector-guard-offset=1024 
-mstack-protector-guard-reg=sp_el0 \
 // RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=AARCH64
+// RUN: %clang_cc1 -mstack-protector-guard=tls -triple riscv64-unknown-elf \
+// RUN:   -mstack-protector-guard-offset=44 -mstack-protector-guard-reg=tp \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=RISCV
 void foo(int*);
 void bar(int x) {
   int baz[x];
@@ -23,3 +26,8 @@ void bar(int x) {
 // AARCH64: [[ATTR1]] = !{i32 1, !"stack-protector-guard", !"sysreg"}
 // AARCH64: [[ATTR2]] = !{i32 1, !"stack-protector-guard-reg", !"sp_el0"}
 // AARCH64: [[ATTR3]] = !{i32 1, !"stack-protector-guard-offset", i32 1024}
+
+// RISCV: !llvm.module.flags = !{{{.*}}[[ATTR1:![0-9]+]], [[ATTR2:![0-9]+]], 
[[ATTR3:![0-9]+]], [[ATTR4:![0-9]+]]}
+// RISCV: [[ATTR1]] = !{i32 1, !"stack-protector-guard", !"tls"}
+// RISCV: [[ATTR2]] = !{i32 1, !"stack-protector-guard-reg", !"tp"}
+// RISCV: [[ATTR3]] = !{i32 1, !"stack-protector-guard-offset", i32 44}
diff --git a/clang/test/Driver/stack-protector-guard.c 
b/clang/test/Driver/stack-protector-guard.c
index af4e11f8eaabce..d8475a70e3709f 100644
--- a/clang/test/Driver/stack-protector-guard.c
+++ b/clang/test/Driver/stack-protector-guard.c
@@ -85,3 +85,22 @@
 // CHECK-AARCH64: "-cc1" {{.*}}"-mstack-protector-guard=sysreg" 
"-mstack-protector-guard-offset=0" "-mstack-protector-guard-reg=sp_el0"
 // INVALID-VALUE-AARCH64: error: invalid value 'tls' in 
'mstack-protector-guard=', expected one of: sysreg global
 // INVALID-REG-AARCH64: error: invalid value 'foo' in 
'mstack-protector-guard-reg='
+
+// RUN: %clang -### -target riscv64-unknown-elf -mstack-protector-guard=tls 
-mstack-protector-guard-offset=24 -mstack-protector-guard-reg=tp %s 2>&1 | \
+// RUN:   FileCheck -v -check-prefix=CHECK-TLS-RISCV %s
+// RUN: %clang -### -target riscv64-unknown-elf -mstack-protector-guard=global 
%s 2>&1 | \
+// RUN:   FileCheck -check-prefix=CHECK-GLOBAL %s
+
+// CHECK-TLS-RISCV: "-cc1" {{.*}}"-mstack-protector-guard=tls" 
"-mstack-protector-guard-offset=24" "-mstack-protector-guard-reg=tp"
+
+// RUN: not %clang -target riscv64-unknown-elf -mstack-protector-guard=tls %s 
2>&1 | \
+// RUN:   FileCheck -check-prefix=MISSING-OFFSET %s
+
+// RUN: not %clang -target riscv64-unknown-elf -mstack-protector-guard=sysreg 
%s 2>&1 | \
+// RUN:   FileCheck -check-prefix=INVALID-VALUE2 %s
+
+// RUN: not %clang -target riscv64-unknown-elf -mstack-protector-guard=tls \
+// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=sp %s 
2>&1 | \
+// RUN:   FileCheck -check-prefix=INVALID-REG-RISCV %s
+
+// INVALID-REG-RISCV: error: invalid value 'sp' in 
'mstack-protector-guard-reg=', expected one of: tp

>From b096174dfc36673ea60617730c4e9f605c2c8596 Mon Sep 17 00:00:00 2001
From: Keith Packard <kei...@keithp.com>
Date: Mon, 16 Sep 2024 12:36:06 -0700
Subject: [PATCH 4/9] [CodeGen][RISCV] Add test for TLS stack canary

Make sure the code generated for a TLS-relative stack guard canary
references the right location before and after intervening function
code.

Signed-off-by: Keith Packard <kei...@keithp.com>
---
 llvm/test/CodeGen/RISCV/stack-guard-tls.ll | 41 ++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/stack-guard-tls.ll

diff --git a/llvm/test/CodeGen/RISCV/stack-guard-tls.ll 
b/llvm/test/CodeGen/RISCV/stack-guard-tls.ll
new file mode 100644
index 00000000000000..2992097937febf
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/stack-guard-tls.ll
@@ -0,0 +1,41 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN:     | FileCheck %s
+
+define void @foo(i64 %t) sspstrong nounwind {
+; CHECK-LABEL: foo:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    addi sp, sp, -32
+; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
+; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
+; CHECK-NEXT:    addi s0, sp, 32
+; CHECK-NEXT:    ld a1, 500(tp)
+; CHECK-NEXT:    sd a1, -24(s0)
+; CHECK-NEXT:    slli a0, a0, 2
+; CHECK-NEXT:    addi a0, a0, 15
+; CHECK-NEXT:    andi a0, a0, -16
+; CHECK-NEXT:    sub a0, sp, a0
+; CHECK-NEXT:    mv sp, a0
+; CHECK-NEXT:    call baz
+; CHECK-NEXT:    ld a0, 500(tp)
+; CHECK-NEXT:    ld a1, -24(s0)
+; CHECK-NEXT:    bne a0, a1, .LBB0_2
+; CHECK-NEXT:  # %bb.1: # %SP_return
+; CHECK-NEXT:    addi sp, s0, -32
+; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
+; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
+; CHECK-NEXT:    addi sp, sp, 32
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB0_2: # %CallStackCheckFailBlk
+; CHECK-NEXT:    call __stack_chk_fail
+  %vla = alloca i32, i64 %t, align 4
+  call void @baz(ptr %vla)
+  ret void
+}
+
+declare void @baz(ptr)
+
+!llvm.module.flags = !{!1, !2, !3}
+!1 = !{i32 2, !"stack-protector-guard", !"tls"}
+!2 = !{i32 2, !"stack-protector-guard-reg", !"tp"}
+!3 = !{i32 2, !"stack-protector-guard-offset", i32 500}

>From 89968415fedff0c1c70d95c0bc4bd4017ce275c6 Mon Sep 17 00:00:00 2001
From: Keith Packard <kei...@keithp.com>
Date: Mon, 23 Sep 2024 11:34:21 -0700
Subject: [PATCH 5/9] [CodeGen][RISCV] Add test for global stack canary

Make sure the code generated for a global stack guard canary
references __stack_chk_guard before and after intervening function
code.

Signed-off-by: Keith Packard <kei...@keithp.com>
---
 llvm/test/CodeGen/RISCV/stack-guard-global.ll | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/stack-guard-global.ll

diff --git a/llvm/test/CodeGen/RISCV/stack-guard-global.ll 
b/llvm/test/CodeGen/RISCV/stack-guard-global.ll
new file mode 100644
index 00000000000000..da26ceb5e9c01f
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/stack-guard-global.ll
@@ -0,0 +1,42 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN:     | FileCheck %s
+
+define void @foo(i64 %t) sspstrong nounwind {
+; CHECK-LABEL: foo:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    addi sp, sp, -32
+; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
+; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
+; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
+; CHECK-NEXT:    addi s0, sp, 32
+; CHECK-NEXT:    lui s1, %hi(__stack_chk_guard)
+; CHECK-NEXT:    ld a1, %lo(__stack_chk_guard)(s1)
+; CHECK-NEXT:    sd a1, -32(s0)
+; CHECK-NEXT:    slli a0, a0, 2
+; CHECK-NEXT:    addi a0, a0, 15
+; CHECK-NEXT:    andi a0, a0, -16
+; CHECK-NEXT:    sub a0, sp, a0
+; CHECK-NEXT:    mv sp, a0
+; CHECK-NEXT:    call baz
+; CHECK-NEXT:    ld a0, %lo(__stack_chk_guard)(s1)
+; CHECK-NEXT:    ld a1, -32(s0)
+; CHECK-NEXT:    bne a0, a1, .LBB0_2
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:    addi sp, s0, -32
+; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
+; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
+; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
+; CHECK-NEXT:    addi sp, sp, 32
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB0_2:
+; CHECK-NEXT:    call __stack_chk_fail
+  %vla = alloca i32, i64 %t, align 4
+  call void @baz(ptr %vla)
+  ret void
+}
+
+declare void @baz(ptr)
+
+!llvm.module.flags = !{!1}
+!1 = !{i32 2, !"stack-protector-guard", !"global"}

>From 6b681663caf3c6a94795865a1ccbcfacf3ceaf62 Mon Sep 17 00:00:00 2001
From: Keith Packard <kei...@keithp.com>
Date: Mon, 16 Sep 2024 15:41:38 +0200
Subject: [PATCH 6/9] [PowerPC][ISelLowering] Support
 -mstack-protector-guard=tls

Add support for using a thread-local variable with a specified offset
for holding the stack guard canary value.

Signed-off-by: Keith Packard <kei...@keithp.com>
---
 clang/lib/Driver/ToolChains/Clang.cpp       | 22 +++++++++++++++++----
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 21 ++++++++++++++++++++
 llvm/lib/Target/PowerPC/PPCISelLowering.h   |  1 +
 3 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index c9baca00ec6f3b..183820e5d7f187 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3605,7 +3605,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
     StringRef Value = A->getValue();
     if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
         !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-        !EffectiveTriple.isRISCV())
+        !EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC64() &&
+        !EffectiveTriple.isPPC32())
       D.Diag(diag::err_drv_unsupported_opt_for_target)
           << A->getAsString(Args) << TripleStr;
     if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3645,7 +3646,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
           << A->getOption().getName() << Value << "sysreg global";
       return;
     }
-    if (EffectiveTriple.isRISCV()) {
+    if (EffectiveTriple.isRISCV() || EffectiveTriple.isPPC64() ||
+        EffectiveTriple.isPPC32()) {
       if (Value != "tls" && Value != "global") {
         D.Diag(diag::err_drv_invalid_value_with_suggestion)
             << A->getOption().getName() << Value << "tls global";
@@ -3666,7 +3668,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
     StringRef Value = A->getValue();
     if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
         !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
-        !EffectiveTriple.isRISCV())
+        !EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC64() &&
+        !EffectiveTriple.isPPC32())
       D.Diag(diag::err_drv_unsupported_opt_for_target)
           << A->getAsString(Args) << TripleStr;
     int Offset;
@@ -3686,7 +3689,8 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
   if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
     StringRef Value = A->getValue();
     if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
-        !EffectiveTriple.isRISCV())
+        !EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC64() &&
+        !EffectiveTriple.isPPC32())
       D.Diag(diag::err_drv_unsupported_opt_for_target)
           << A->getAsString(Args) << TripleStr;
     if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3703,6 +3707,16 @@ static void RenderSSPOptions(const Driver &D, const 
ToolChain &TC,
           << A->getOption().getName() << Value << "tp";
       return;
     }
+    if (EffectiveTriple.isPPC64() && Value != "r13") {
+      D.Diag(diag::err_drv_invalid_value_with_suggestion)
+          << A->getOption().getName() << Value << "r13";
+      return;
+    }
+    if (EffectiveTriple.isPPC32() && Value != "r2") {
+      D.Diag(diag::err_drv_invalid_value_with_suggestion)
+          << A->getOption().getName() << Value << "r2";
+      return;
+    }
     A->render(Args, CmdArgs);
   }
 
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp 
b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index d9847a21489e63..455b62aed4c027 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -17913,6 +17913,27 @@ Value *PPCTargetLowering::getSDagStackGuard(const 
Module &M) const {
   return TargetLowering::getSDagStackGuard(M);
 }
 
+static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
+  Module *M = IRB.GetInsertBlock()->getModule();
+  Function *ThreadPointerFunc =
+      Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
+  return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
+                                IRB.CreateCall(ThreadPointerFunc), Offset);
+}
+
+Value *PPCTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
+  Module *M = IRB.GetInsertBlock()->getModule();
+
+  if (M->getStackProtectorGuard() == "tls") {
+    // Specially, some users may customize the base reg and offset.
+    int Offset = M->getStackProtectorGuardOffset();
+    return useTpOffset(IRB, Offset);
+  }
+
+  return TargetLowering::getIRStackGuard(IRB);
+}
+
+
 bool PPCTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
                                      bool ForCodeSize) const {
   if (!VT.isSimple() || !Subtarget.hasVSX())
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h 
b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 8907c3c5a81c3c..8d993d467f2b00 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -1140,6 +1140,7 @@ namespace llvm {
     bool useLoadStackGuardNode() const override;
     void insertSSPDeclarations(Module &M) const override;
     Value *getSDagStackGuard(const Module &M) const override;
+    Value *getIRStackGuard(IRBuilderBase &IRB) const override;
 
     bool isFPImmLegal(const APFloat &Imm, EVT VT,
                       bool ForCodeSize) const override;

>From d0beb6a8484b05712f54448bf798b781573ec006 Mon Sep 17 00:00:00 2001
From: Keith Packard <kei...@keithp.com>
Date: Mon, 16 Sep 2024 11:27:19 -0700
Subject: [PATCH 7/9] [clang][PowerPC] Add stack protector tests

Add tests ensuring that the driver correctly handles stack protector
guard options.

Signed-off-by: Keith Packard <kei...@keithp.com>
---
 clang/test/CodeGen/stack-protector-guard.c |  8 +++
 clang/test/Driver/stack-protector-guard.c  | 57 ++++++++++++++++++++--
 2 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/clang/test/CodeGen/stack-protector-guard.c 
b/clang/test/CodeGen/stack-protector-guard.c
index 4777367c94e733..51af6fb6311be8 100644
--- a/clang/test/CodeGen/stack-protector-guard.c
+++ b/clang/test/CodeGen/stack-protector-guard.c
@@ -12,6 +12,9 @@
 // RUN: %clang_cc1 -mstack-protector-guard=tls -triple riscv64-unknown-elf \
 // RUN:   -mstack-protector-guard-offset=44 -mstack-protector-guard-reg=tp \
 // RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=RISCV
+// RUN: %clang_cc1 -mstack-protector-guard=tls -triple powerpc64-unknown-elf \
+// RUN:   -mstack-protector-guard-offset=52 -mstack-protector-guard-reg=r13 \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=POWERPC64
 void foo(int*);
 void bar(int x) {
   int baz[x];
@@ -31,3 +34,8 @@ void bar(int x) {
 // RISCV: [[ATTR1]] = !{i32 1, !"stack-protector-guard", !"tls"}
 // RISCV: [[ATTR2]] = !{i32 1, !"stack-protector-guard-reg", !"tp"}
 // RISCV: [[ATTR3]] = !{i32 1, !"stack-protector-guard-offset", i32 44}
+
+// POWERPC64: !llvm.module.flags = !{{{.*}}[[ATTR1:![0-9]+]], 
[[ATTR2:![0-9]+]], [[ATTR3:![0-9]+]], [[ATTR4:![0-9]+]]}
+// POWERPC64: [[ATTR1]] = !{i32 1, !"stack-protector-guard", !"tls"}
+// POWERPC64: [[ATTR2]] = !{i32 1, !"stack-protector-guard-reg", !"r13"}
+// POWERPC64: [[ATTR3]] = !{i32 1, !"stack-protector-guard-offset", i32 52}
diff --git a/clang/test/Driver/stack-protector-guard.c 
b/clang/test/Driver/stack-protector-guard.c
index d8475a70e3709f..666c83079e5191 100644
--- a/clang/test/Driver/stack-protector-guard.c
+++ b/clang/test/Driver/stack-protector-guard.c
@@ -17,15 +17,15 @@
 // RUN:   FileCheck -check-prefix=CHECK-SYM %s
 
 // Invalid arch
-// RUN: not %clang -target powerpc64le-linux-gnu -mstack-protector-guard=tls 
%s 2>&1 | \
+// RUN: not %clang -target mipsel-linux-gnu -mstack-protector-guard=tls %s 
2>&1 | \
 // RUN:   FileCheck -check-prefix=INVALID-ARCH %s
 // INVALID-ARCH: unsupported option '-mstack-protector-guard=tls' for target
 
-// RUN: not %clang -target powerpc64le-linux-gnu 
-mstack-protector-guard-reg=fs %s 2>&1 | \
+// RUN: not %clang -target mipsel-linux-gnu -mstack-protector-guard-reg=fs %s 
2>&1 | \
 // RUN:   FileCheck -check-prefix=INVALID-ARCH2 %s
 // INVALID-ARCH2: unsupported option '-mstack-protector-guard-reg=fs' for 
target
 
-// RUN: not %clang -target powerpc64le-linux-gnu 
-mstack-protector-guard-offset=10 %s 2>&1 | \
+// RUN: not %clang -target mipsel-linux-gnu -mstack-protector-guard-offset=10 
%s 2>&1 | \
 // RUN:   FileCheck -check-prefix=INVALID-ARCH3 %s
 // INVALID-ARCH3: unsupported option '-mstack-protector-guard-offset=10' for 
target
 
@@ -104,3 +104,54 @@
 // RUN:   FileCheck -check-prefix=INVALID-REG-RISCV %s
 
 // INVALID-REG-RISCV: error: invalid value 'sp' in 
'mstack-protector-guard-reg=', expected one of: tp
+
+// RUN: %clang -### -target powerpc64-unknown-elf -mstack-protector-guard=tls 
-mstack-protector-guard-offset=24 -mstack-protector-guard-reg=r13 %s 2>&1 | \
+// RUN:   FileCheck -v -check-prefix=CHECK-TLS-POWERPC64 %s
+// RUN: %clang -### -target powerpc64-unknown-linux-gnu 
-mstack-protector-guard=global %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=CHECK-GLOBAL %s
+
+// RUN: not %clang -target powerpc64-unknown-linux-gnu 
-mstack-protector-guard=tls %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=MISSING-OFFSET %s
+
+// RUN: not %clang -target powerpc64-unknown-elf 
-mstack-protector-guard=sysreg %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=INVALID-VALUE2 %s
+
+// RUN: not %clang -target powerpc64-unknown-elf -mstack-protector-guard=tls \
+// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=r12 %s 
2>&1 | \
+// RUN:   FileCheck -check-prefix=INVALID-REG-POWERPC64 %s
+
+// CHECK-TLS-POWERPC64: "-cc1" {{.*}}"-mstack-protector-guard=tls" 
"-mstack-protector-guard-offset=24" "-mstack-protector-guard-reg=r13"
+// INVALID-REG-POWERPC64: error: invalid value 'r12' in 
'mstack-protector-guard-reg=', expected one of: r13
+
+// RUN: %clang -### -target powerpc64le-unknown-elf 
-mstack-protector-guard=tls -mstack-protector-guard-offset=24 
-mstack-protector-guard-reg=r13 %s 2>&1 | \
+// RUN:   FileCheck -v -check-prefix=CHECK-TLS-POWERPC64 %s
+// RUN: %clang -### -target powerpc64le-unknown-elf 
-mstack-protector-guard=global %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=CHECK-GLOBAL %s
+
+// RUN: not %clang -target powerpc64le-unknown-elf -mstack-protector-guard=tls 
%s 2>&1 | \
+// RUN:   FileCheck -check-prefix=MISSING-OFFSET %s
+
+// RUN: not %clang -target powerpc64le-unknown-elf 
-mstack-protector-guard=sysreg %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=INVALID-VALUE2 %s
+
+// RUN: not %clang -target powerpc64le-unknown-elf -mstack-protector-guard=tls 
\
+// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=r12 %s 
2>&1 | \
+// RUN:   FileCheck -check-prefix=INVALID-REG-POWERPC64 %s
+
+// RUN: %clang -### -target ppc32-unknown-elf -mstack-protector-guard=tls 
-mstack-protector-guard-offset=24 -mstack-protector-guard-reg=r2 %s 2>&1 | \
+// RUN:   FileCheck -v -check-prefix=CHECK-TLS-POWERPC32 %s
+// RUN: %clang -### -target ppc32-unknown-elf -mstack-protector-guard=global 
%s 2>&1 | \
+// RUN:   FileCheck -check-prefix=CHECK-GLOBAL %s
+
+// RUN: not %clang -target ppc32-unknown-elf -mstack-protector-guard=tls %s 
2>&1 | \
+// RUN:   FileCheck -check-prefix=MISSING-OFFSET %s
+
+// RUN: not %clang -target ppc32-unknown-elf -mstack-protector-guard=sysreg %s 
2>&1 | \
+// RUN:   FileCheck -check-prefix=INVALID-VALUE2 %s
+
+// RUN: not %clang -target ppc32-unknown-elf -mstack-protector-guard=tls \
+// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=r3 %s 
2>&1 | \
+// RUN:   FileCheck -check-prefix=INVALID-REG-POWERPC32 %s
+
+// CHECK-TLS-POWERPC32: "-cc1" {{.*}}"-mstack-protector-guard=tls" 
"-mstack-protector-guard-offset=24" "-mstack-protector-guard-reg=r2"
+// INVALID-REG-POWERPC32: error: invalid value 'r3' in 
'mstack-protector-guard-reg=', expected one of: r2

>From 091da2d71a8b1f7c12e218350f1ef918dca935fb Mon Sep 17 00:00:00 2001
From: Keith Packard <kei...@keithp.com>
Date: Mon, 16 Sep 2024 12:36:06 -0700
Subject: [PATCH 8/9] [CodeGen][PowerPC] Add codegen test for TLS stack canary

Make sure the code generated for a TLS-relative stack guard canary
references the right location before and after intervening function
code.

Signed-off-by: Keith Packard <kei...@keithp.com>
---
 llvm/test/CodeGen/PowerPC/stack-guard-tls.ll | 114 +++++++++++++++++++
 1 file changed, 114 insertions(+)
 create mode 100644 llvm/test/CodeGen/PowerPC/stack-guard-tls.ll

diff --git a/llvm/test/CodeGen/PowerPC/stack-guard-tls.ll 
b/llvm/test/CodeGen/PowerPC/stack-guard-tls.ll
new file mode 100644
index 00000000000000..fa50db0607f9aa
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/stack-guard-tls.ll
@@ -0,0 +1,114 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -mtriple=powerpc64 -verify-machineinstrs < %s \
+; RUN:     | FileCheck %s --check-prefixes=BE64
+; RUN: llc -mtriple=powerpc64le -verify-machineinstrs < %s \
+; RUN:     | FileCheck %s --check-prefixes=LE64
+; RUN: llc -mtriple=ppc32 -verify-machineinstrs < %s \
+; RUN:     | FileCheck %s --check-prefixes=LE32
+
+define void @foo(i64 %t) sspstrong nounwind {
+; BE64-LABEL: foo:
+; BE64:       # %bb.0:
+; BE64-NEXT:    mflr 0
+; BE64-NEXT:    std 31, -8(1)
+; BE64-NEXT:    stdu 1, -144(1)
+; BE64-NEXT:    std 0, 160(1)
+; BE64-NEXT:    sldi 3, 3, 2
+; BE64-NEXT:    mr 31, 1
+; BE64-NEXT:    ld 4, 500(13)
+; BE64-NEXT:    addi 3, 3, 15
+; BE64-NEXT:    rldicr 3, 3, 0, 59
+; BE64-NEXT:    neg 3, 3
+; BE64-NEXT:    std 4, 128(31)
+; BE64-NEXT:    addi 4, 31, 144
+; BE64-NEXT:    stdux 4, 1, 3
+; BE64-NEXT:    addi 3, 1, 112
+; BE64-NEXT:    bl baz
+; BE64-NEXT:    nop
+; BE64-NEXT:    ld 3, 500(13)
+; BE64-NEXT:    ld 4, 128(31)
+; BE64-NEXT:    cmpld 3, 4
+; BE64-NEXT:    bne- 0, .LBB0_2
+; BE64-NEXT:  # %bb.1: # %SP_return
+; BE64-NEXT:    ld 1, 0(1)
+; BE64-NEXT:    ld 0, 16(1)
+; BE64-NEXT:    ld 31, -8(1)
+; BE64-NEXT:    mtlr 0
+; BE64-NEXT:    blr
+; BE64-NEXT:  .LBB0_2: # %CallStackCheckFailBlk
+; BE64-NEXT:    bl __stack_chk_fail
+; BE64-NEXT:    nop
+;
+; LE64-LABEL: foo:
+; LE64:       # %bb.0:
+; LE64-NEXT:    mflr 0
+; LE64-NEXT:    std 31, -8(1)
+; LE64-NEXT:    stdu 1, -64(1)
+; LE64-NEXT:    sldi 3, 3, 2
+; LE64-NEXT:    std 0, 80(1)
+; LE64-NEXT:    mr 31, 1
+; LE64-NEXT:    addi 3, 3, 15
+; LE64-NEXT:    ld 4, 500(13)
+; LE64-NEXT:    rldicr 3, 3, 0, 59
+; LE64-NEXT:    std 4, 48(31)
+; LE64-NEXT:    addi 4, 31, 64
+; LE64-NEXT:    neg 3, 3
+; LE64-NEXT:    stdux 4, 1, 3
+; LE64-NEXT:    addi 3, 1, 32
+; LE64-NEXT:    bl baz
+; LE64-NEXT:    nop
+; LE64-NEXT:    ld 3, 500(13)
+; LE64-NEXT:    ld 4, 48(31)
+; LE64-NEXT:    cmpld 3, 4
+; LE64-NEXT:    bne- 0, .LBB0_2
+; LE64-NEXT:  # %bb.1: # %SP_return
+; LE64-NEXT:    ld 1, 0(1)
+; LE64-NEXT:    ld 0, 16(1)
+; LE64-NEXT:    ld 31, -8(1)
+; LE64-NEXT:    mtlr 0
+; LE64-NEXT:    blr
+; LE64-NEXT:  .LBB0_2: # %CallStackCheckFailBlk
+; LE64-NEXT:    bl __stack_chk_fail
+; LE64-NEXT:    nop
+;
+; LE32-LABEL: foo:
+; LE32:       # %bb.0:
+; LE32-NEXT:    mflr 0
+; LE32-NEXT:    stwu 1, -32(1)
+; LE32-NEXT:    stw 31, 28(1)
+; LE32-NEXT:    slwi 4, 4, 2
+; LE32-NEXT:    stw 0, 36(1)
+; LE32-NEXT:    addi 4, 4, 15
+; LE32-NEXT:    lwz 3, 500(2)
+; LE32-NEXT:    mr 31, 1
+; LE32-NEXT:    rlwinm 4, 4, 0, 0, 27
+; LE32-NEXT:    neg 4, 4
+; LE32-NEXT:    stw 3, 24(31)
+; LE32-NEXT:    addi 3, 31, 32
+; LE32-NEXT:    stwux 3, 1, 4
+; LE32-NEXT:    addi 3, 1, 16
+; LE32-NEXT:    bl baz
+; LE32-NEXT:    lwz 3, 500(2)
+; LE32-NEXT:    lwz 4, 24(31)
+; LE32-NEXT:    cmplw 3, 4
+; LE32-NEXT:    bne- 0, .LBB0_2
+; LE32-NEXT:  # %bb.1: # %SP_return
+; LE32-NEXT:    lwz 31, 0(1)
+; LE32-NEXT:    lwz 0, -4(31)
+; LE32-NEXT:    mr 1, 31
+; LE32-NEXT:    mr 31, 0
+; LE32-NEXT:    lwz 0, 4(1)
+; LE32-NEXT:    mtlr 0
+; LE32-NEXT:    blr
+; LE32-NEXT:  .LBB0_2: # %CallStackCheckFailBlk
+; LE32-NEXT:    bl __stack_chk_fail
+  %vla = alloca i32, i64 %t, align 4
+  call void @baz(ptr %vla)
+  ret void
+}
+
+declare void @baz(ptr)
+
+!llvm.module.flags = !{!1, !2}
+!1 = !{i32 2, !"stack-protector-guard", !"tls"}
+!2 = !{i32 2, !"stack-protector-guard-offset", i32 500}

>From 7dcfa3c3101b5b80a8e323cfea7ae8c4013c5ba6 Mon Sep 17 00:00:00 2001
From: Keith Packard <kei...@keithp.com>
Date: Mon, 23 Sep 2024 11:34:21 -0700
Subject: [PATCH 9/9] [CodeGen][PowerPC] Add codegen test for global stack
 canary

Make sure the code generated for a global stack guard canary
references __stack_chk_guard before and after intervening function
code.

Signed-off-by: Keith Packard <kei...@keithp.com>
---
 .../CodeGen/PowerPC/stack-guard-global.ll     | 122 ++++++++++++++++++
 1 file changed, 122 insertions(+)
 create mode 100644 llvm/test/CodeGen/PowerPC/stack-guard-global.ll

diff --git a/llvm/test/CodeGen/PowerPC/stack-guard-global.ll 
b/llvm/test/CodeGen/PowerPC/stack-guard-global.ll
new file mode 100644
index 00000000000000..022a62a4b0918d
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/stack-guard-global.ll
@@ -0,0 +1,122 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -mtriple=powerpc64 -verify-machineinstrs < %s \
+; RUN:     | FileCheck %s --check-prefixes=BE64
+; RUN: llc -mtriple=powerpc64le -verify-machineinstrs < %s \
+; RUN:     | FileCheck %s --check-prefixes=LE64
+; RUN: llc -mtriple=ppc32 -verify-machineinstrs < %s \
+; RUN:     | FileCheck %s --check-prefixes=LE32
+
+define void @foo(i64 %t) sspstrong nounwind {
+; BE64-LABEL: foo:
+; BE64:       # %bb.0:
+; BE64-NEXT:    mflr 0
+; BE64-NEXT:    std 31, -8(1)
+; BE64-NEXT:    stdu 1, -144(1)
+; BE64-NEXT:    mr 31, 1
+; BE64-NEXT:    std 0, 160(1)
+; BE64-NEXT:    std 30, 128(31) # 8-byte Folded Spill
+; BE64-NEXT:    addis 30, 2, __stack_chk_guard@toc@ha
+; BE64-NEXT:    sldi 3, 3, 2
+; BE64-NEXT:    ld 4, __stack_chk_guard@toc@l(30)
+; BE64-NEXT:    addi 3, 3, 15
+; BE64-NEXT:    rldicr 3, 3, 0, 59
+; BE64-NEXT:    neg 3, 3
+; BE64-NEXT:    std 4, 120(31)
+; BE64-NEXT:    addi 4, 31, 144
+; BE64-NEXT:    stdux 4, 1, 3
+; BE64-NEXT:    addi 3, 1, 112
+; BE64-NEXT:    bl baz
+; BE64-NEXT:    nop
+; BE64-NEXT:    ld 3, __stack_chk_guard@toc@l(30)
+; BE64-NEXT:    ld 4, 120(31)
+; BE64-NEXT:    cmpld 3, 4
+; BE64-NEXT:    bne 0, .LBB0_2
+; BE64-NEXT:  # %bb.1:
+; BE64-NEXT:    ld 30, 128(31) # 8-byte Folded Reload
+; BE64-NEXT:    ld 1, 0(1)
+; BE64-NEXT:    ld 0, 16(1)
+; BE64-NEXT:    ld 31, -8(1)
+; BE64-NEXT:    mtlr 0
+; BE64-NEXT:    blr
+; BE64-NEXT:  .LBB0_2:
+; BE64-NEXT:    bl __stack_chk_fail
+; BE64-NEXT:    nop
+;
+; LE64-LABEL: foo:
+; LE64:       # %bb.0:
+; LE64-NEXT:    mflr 0
+; LE64-NEXT:    std 31, -8(1)
+; LE64-NEXT:    stdu 1, -64(1)
+; LE64-NEXT:    mr 31, 1
+; LE64-NEXT:    sldi 3, 3, 2
+; LE64-NEXT:    std 0, 80(1)
+; LE64-NEXT:    std 30, 48(31) # 8-byte Folded Spill
+; LE64-NEXT:    addis 30, 2, __stack_chk_guard@toc@ha
+; LE64-NEXT:    addi 3, 3, 15
+; LE64-NEXT:    ld 4, __stack_chk_guard@toc@l(30)
+; LE64-NEXT:    rldicr 3, 3, 0, 59
+; LE64-NEXT:    neg 3, 3
+; LE64-NEXT:    std 4, 40(31)
+; LE64-NEXT:    addi 4, 31, 64
+; LE64-NEXT:    stdux 4, 1, 3
+; LE64-NEXT:    addi 3, 1, 32
+; LE64-NEXT:    bl baz
+; LE64-NEXT:    nop
+; LE64-NEXT:    ld 3, __stack_chk_guard@toc@l(30)
+; LE64-NEXT:    ld 4, 40(31)
+; LE64-NEXT:    cmpld 3, 4
+; LE64-NEXT:    bne 0, .LBB0_2
+; LE64-NEXT:  # %bb.1:
+; LE64-NEXT:    ld 30, 48(31) # 8-byte Folded Reload
+; LE64-NEXT:    ld 1, 0(1)
+; LE64-NEXT:    ld 0, 16(1)
+; LE64-NEXT:    ld 31, -8(1)
+; LE64-NEXT:    mtlr 0
+; LE64-NEXT:    blr
+; LE64-NEXT:  .LBB0_2:
+; LE64-NEXT:    bl __stack_chk_fail
+; LE64-NEXT:    nop
+;
+; LE32-LABEL: foo:
+; LE32:       # %bb.0:
+; LE32-NEXT:    mflr 0
+; LE32-NEXT:    stwu 1, -32(1)
+; LE32-NEXT:    stw 31, 28(1)
+; LE32-NEXT:    mr 31, 1
+; LE32-NEXT:    stw 0, 36(1)
+; LE32-NEXT:    slwi 4, 4, 2
+; LE32-NEXT:    stw 30, 24(31) # 4-byte Folded Spill
+; LE32-NEXT:    lis 30, __stack_chk_guard@ha
+; LE32-NEXT:    lwz 3, __stack_chk_guard@l(30)
+; LE32-NEXT:    addi 4, 4, 15
+; LE32-NEXT:    rlwinm 4, 4, 0, 0, 27
+; LE32-NEXT:    neg 4, 4
+; LE32-NEXT:    stw 3, 20(31)
+; LE32-NEXT:    addi 3, 31, 32
+; LE32-NEXT:    stwux 3, 1, 4
+; LE32-NEXT:    addi 3, 1, 16
+; LE32-NEXT:    bl baz
+; LE32-NEXT:    lwz 3, __stack_chk_guard@l(30)
+; LE32-NEXT:    lwz 4, 20(31)
+; LE32-NEXT:    cmplw 3, 4
+; LE32-NEXT:    bne 0, .LBB0_2
+; LE32-NEXT:  # %bb.1:
+; LE32-NEXT:    lwz 30, 24(31) # 4-byte Folded Reload
+; LE32-NEXT:    lwz 31, 0(1)
+; LE32-NEXT:    lwz 0, -4(31)
+; LE32-NEXT:    mr 1, 31
+; LE32-NEXT:    mr 31, 0
+; LE32-NEXT:    lwz 0, 4(1)
+; LE32-NEXT:    mtlr 0
+; LE32-NEXT:    blr
+; LE32-NEXT:  .LBB0_2:
+; LE32-NEXT:    bl __stack_chk_fail
+  %vla = alloca i32, i64 %t, align 4
+  call void @baz(ptr %vla)
+  ret void
+}
+
+declare void @baz(ptr)
+
+!llvm.module.flags = !{!1}
+!1 = !{i32 2, !"stack-protector-guard", !"global"}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to