[compiler-rt] [libcxx] [mlir] [libc] [flang] [llvm] [clang] [openmp] [clang-tools-extra] [libunwind] [X86][ISel] Don't select MOV/ADD64ri32 for tglobaltlsaddr under large code models (PR #77175)

2024-01-05 Thread Nicholas Mosier via cfe-commits

https://github.com/nmosier updated 
https://github.com/llvm/llvm-project/pull/77175

>From b6351e796868be27075518fb51830bf79c60cdf6 Mon Sep 17 00:00:00 2001
From: Nicholas Mosier 
Date: Sat, 6 Jan 2024 03:36:03 +
Subject: [PATCH] [X86][ISel] Select MOV/ADD64ri32 for tglobaltlsaddr only
 under small code models

This patch fixes a bug (GitHub issue #77128) that caused the compiler
to emit 32-bit (rather than 64-bit) relocations for TLS offsets under a
medium/large code model for x86-64 targets, resulting in link-time errors.

The root cause of the bug is an X86 instruction selection pattern that
errantly matches tglobaltlsaddr SDNodes to target MOV64ri32/ADD64ri32 SDNodes
during the Select phase of instruction selection, regardless of the code
model.

This patch adds the requirement `Requires<[NearData]>` to both X86 selection
patterns, ensuring that they only match when the code model is 
tiny/small/kernel.
It also adds a new test (llvm/test/CodeGen/X86/tls-largecode.ll) to ensure the 
patterns are not matched for medium/large code models.
---
 llvm/lib/Target/X86/X86InstrCompiler.td |  4 +--
 llvm/test/CodeGen/X86/tls-codemodels.ll | 36 +
 2 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/tls-codemodels.ll

diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td 
b/llvm/lib/Target/X86/X86InstrCompiler.td
index c77c77ee4a3eeb..67fb593e391d34 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1267,10 +1267,10 @@ def : Pat<(i64 (X86RecoverFrameAlloc mcsym:$dst)), 
(MOV64ri mcsym:$dst)>;
 // tls has some funny stuff here...
 // This corresponds to movabs $foo@tpoff, %rax
 def : Pat<(i64 (X86Wrapper tglobaltlsaddr :$dst)),
-  (MOV64ri32 tglobaltlsaddr :$dst)>;
+  (MOV64ri32 tglobaltlsaddr :$dst)>, Requires<[NearData]>;
 // This corresponds to add $foo@tpoff, %rax
 def : Pat<(add GR64:$src1, (X86Wrapper tglobaltlsaddr :$dst)),
-  (ADD64ri32 GR64:$src1, tglobaltlsaddr :$dst)>;
+  (ADD64ri32 GR64:$src1, tglobaltlsaddr :$dst)>, Requires<[NearData]>;
 
 
 // Direct PC relative function call for small code model. 32-bit displacement
diff --git a/llvm/test/CodeGen/X86/tls-codemodels.ll 
b/llvm/test/CodeGen/X86/tls-codemodels.ll
new file mode 100644
index 00..644e07300f3928
--- /dev/null
+++ b/llvm/test/CodeGen/X86/tls-codemodels.ll
@@ -0,0 +1,36 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 4
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -code-model=small | 
FileCheck %s --check-prefix=CHECK-SMALL
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -code-model=kernel | 
FileCheck %s --check-prefix=CHECK-KERNEL
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -code-model=medium | 
FileCheck %s --check-prefix=CHECK-MEDIUM
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -code-model=large | 
FileCheck %s --check-prefix=CHECK-LARGE
+
+@x = dso_local thread_local global i32 0, align 4
+
+define dso_local void @test() local_unnamed_addr {
+; CHECK-SMALL-LABEL: test:
+; CHECK-SMALL:   # %bb.0: # %entry
+; CHECK-SMALL-NEXT:movl $0, %fs:x@TPOFF
+; CHECK-SMALL-NEXT:retq
+;
+; CHECK-KERNEL-LABEL: test:
+; CHECK-KERNEL:   # %bb.0: # %entry
+; CHECK-KERNEL-NEXT:movl $0, %fs:x@TPOFF
+; CHECK-KERNEL-NEXT:retq
+;
+; CHECK-MEDIUM-LABEL: test:
+; CHECK-MEDIUM:   # %bb.0: # %entry
+; CHECK-MEDIUM-NEXT:movl $0, %fs:x@TPOFF
+; CHECK-MEDIUM-NEXT:retq
+;
+; CHECK-LARGE-LABEL: test:
+; CHECK-LARGE:   # %bb.0: # %entry
+; CHECK-LARGE-NEXT:movabsq $x@TPOFF, %rax
+; CHECK-LARGE-NEXT:movl $0, %fs:(%rax)
+; CHECK-LARGE-NEXT:retq
+entry:
+  %0 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @x)
+  store i32 0, ptr %0, align 4
+  ret void
+}
+
+declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)

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


[clang-tools-extra] [libcxx] [libc] [clang] [mlir] [llvm] [compiler-rt] [flang] [openmp] [libunwind] [X86][ISel] Don't select MOV/ADD64ri32 for tglobaltlsaddr under large code models (PR #77175)

2024-01-05 Thread Nicholas Mosier via cfe-commits

https://github.com/nmosier closed 
https://github.com/llvm/llvm-project/pull/77175
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [openmp] [clang] [mlir] [lld] [libcxx] [compiler-rt] [X86] Add support for indirect branch tracking in jump tables (PR #77679)

2024-01-10 Thread Nicholas Mosier via cfe-commits

https://github.com/nmosier updated 
https://github.com/llvm/llvm-project/pull/77679

>From 35f91b27825a81b1ba171860b47bf8b0477fd95a Mon Sep 17 00:00:00 2001
From: Nicholas Mosier 
Date: Wed, 10 Jan 2024 19:27:30 +
Subject: [PATCH] [X86] Add support for indirect branch tracking in jump tables

This patch adds support for protecting jump tables with indirect branch 
tracking (IBT).
By default, indirect jump table branches are given a 'notrack' prefix and thus 
not protected with IBT.
This default behavior is suitable for traditional threat models, assuming the 
compiler generates correct jump table code.
However, for threat models encompassing speculative execution vulnerabilities 
(e.g., Spectre),
such notrack'ed indirect branches potentially introduce Spectre-v2-style 
vulnerabilites by allowing them to mis-speculatively jump to arbitrary target 
addresses, not just ENDBRANCH instructions.

To enable indirect branch tracking for jump tables, this patch allows the 
`cf-protection-branch` module flag's value to indicate the level of indirect 
branch protection required.
If `cf-protection-branch == 0` or `cf-protection-branch` is missing entirely, 
then branch protections are applied.
If `cf-protection-branch == 1`, then branch protections are applied for all 
indirect branches except for those that cannot under any circumstances 
non-speculatively jump to the wrong target (namely, indirect jump table 
branches).
If `cf-protection-branch >= 2`, then branch protections are applied to all 
indirect branches, including indirect jump table branches.

To summarize the new interpretation of the `cf-protection-branch` module flag 
under this patch:
* `cf-protection-branch == 1` (currently emitted by clang when passed flag 
`-fcf-protection=branch`) is suitable for hardening code against 
non-speculative control-flow hijacks.
* `cf-protection-branch >= 2` is suitable for additionally hardening code 
against speculative control-flow hijacks (e.g., Spectre v2).
---
 llvm/lib/Target/X86/X86.h |  1 +
 llvm/lib/Target/X86/X86ISelLowering.cpp   | 21 +++
 .../Target/X86/X86IndirectBranchTracking.cpp  | 29 ---
 llvm/lib/Target/X86/X86TargetMachine.cpp  |  1 +
 .../X86/indirect-branch-tracking-jt.mir   | 35 +++
 5 files changed, 77 insertions(+), 10 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/indirect-branch-tracking-jt.mir

diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index 21623a805f5568..277259c74abae2 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -199,6 +199,7 @@ void initializeX86ReturnThunksPass(PassRegistry &);
 void initializeX86SpeculativeExecutionSideEffectSuppressionPass(PassRegistry 
&);
 void initializeX86SpeculativeLoadHardeningPassPass(PassRegistry &);
 void initializeX86TileConfigPass(PassRegistry &);
+void initializeX86IndirectBranchTrackingPassPass(PassRegistry &);
 
 namespace X86AS {
 enum : unsigned {
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp 
b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 5f6f500e49dd2a..71a20b439b5fad 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -56365,12 +56365,21 @@ SDValue 
X86TargetLowering::expandIndirectJTBranch(const SDLoc &dl,
   int JTI,
   SelectionDAG &DAG) const {
   const Module *M = DAG.getMachineFunction().getMMI().getModule();
-  Metadata *IsCFProtectionSupported = M->getModuleFlag("cf-protection-branch");
-  if (IsCFProtectionSupported) {
-// In case control-flow branch protection is enabled, we need to add
-// notrack prefix to the indirect branch.
-// In order to do that we create NT_BRIND SDNode.
-// Upon ISEL, the pattern will convert it to jmp with NoTrack prefix.
+
+  uint64_t CFProtectionBranchLevel = 0;
+  if (Metadata *CFProtectionBranchEnabled =
+  M->getModuleFlag("cf-protection-branch"))
+CFProtectionBranchLevel =
+cast(CFProtectionBranchEnabled)
+->getValue()
+->getUniqueInteger()
+.getLimitedValue();
+
+  if (CFProtectionBranchLevel == 1) {
+// In case control-flow branch protection is enabled but we are not
+// protecting jump table branches, we need to add notrack prefix to the
+// indirect branch. In order to do that we create NT_BRIND SDNode. Upon
+// ISEL, the pattern will convert it to jmp with NoTrack prefix.
 SDValue JTInfo = DAG.getJumpTableDebugInfo(JTI, Value, dl);
 return DAG.getNode(X86ISD::NT_BRIND, dl, MVT::Other, JTInfo, Addr);
   }
diff --git a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp 
b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
index 785bdd83cd998b..0710af3af8469a 100644
--- a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
+++ b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
@@ -22,11 +22,13 @@
 #include "llvm/ADT/Statistic.h"
 

[llvm] [flang] [clang] [clang-tools-extra] [compiler-rt] [libc] [lldb] [libcxxabi] [mlir] [lld] [openmp] [libcxx] [X86] Add support for indirect branch tracking in jump tables (PR #77679)

2024-01-11 Thread Nicholas Mosier via cfe-commits

https://github.com/nmosier updated 
https://github.com/llvm/llvm-project/pull/77679

>From 35f91b27825a81b1ba171860b47bf8b0477fd95a Mon Sep 17 00:00:00 2001
From: Nicholas Mosier 
Date: Wed, 10 Jan 2024 19:27:30 +
Subject: [PATCH] [X86] Add support for indirect branch tracking in jump tables

This patch adds support for protecting jump tables with indirect branch 
tracking (IBT).
By default, indirect jump table branches are given a 'notrack' prefix and thus 
not protected with IBT.
This default behavior is suitable for traditional threat models, assuming the 
compiler generates correct jump table code.
However, for threat models encompassing speculative execution vulnerabilities 
(e.g., Spectre),
such notrack'ed indirect branches potentially introduce Spectre-v2-style 
vulnerabilites by allowing them to mis-speculatively jump to arbitrary target 
addresses, not just ENDBRANCH instructions.

To enable indirect branch tracking for jump tables, this patch allows the 
`cf-protection-branch` module flag's value to indicate the level of indirect 
branch protection required.
If `cf-protection-branch == 0` or `cf-protection-branch` is missing entirely, 
then branch protections are applied.
If `cf-protection-branch == 1`, then branch protections are applied for all 
indirect branches except for those that cannot under any circumstances 
non-speculatively jump to the wrong target (namely, indirect jump table 
branches).
If `cf-protection-branch >= 2`, then branch protections are applied to all 
indirect branches, including indirect jump table branches.

To summarize the new interpretation of the `cf-protection-branch` module flag 
under this patch:
* `cf-protection-branch == 1` (currently emitted by clang when passed flag 
`-fcf-protection=branch`) is suitable for hardening code against 
non-speculative control-flow hijacks.
* `cf-protection-branch >= 2` is suitable for additionally hardening code 
against speculative control-flow hijacks (e.g., Spectre v2).
---
 llvm/lib/Target/X86/X86.h |  1 +
 llvm/lib/Target/X86/X86ISelLowering.cpp   | 21 +++
 .../Target/X86/X86IndirectBranchTracking.cpp  | 29 ---
 llvm/lib/Target/X86/X86TargetMachine.cpp  |  1 +
 .../X86/indirect-branch-tracking-jt.mir   | 35 +++
 5 files changed, 77 insertions(+), 10 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/indirect-branch-tracking-jt.mir

diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index 21623a805f5568..277259c74abae2 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -199,6 +199,7 @@ void initializeX86ReturnThunksPass(PassRegistry &);
 void initializeX86SpeculativeExecutionSideEffectSuppressionPass(PassRegistry 
&);
 void initializeX86SpeculativeLoadHardeningPassPass(PassRegistry &);
 void initializeX86TileConfigPass(PassRegistry &);
+void initializeX86IndirectBranchTrackingPassPass(PassRegistry &);
 
 namespace X86AS {
 enum : unsigned {
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp 
b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 5f6f500e49dd2a..71a20b439b5fad 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -56365,12 +56365,21 @@ SDValue 
X86TargetLowering::expandIndirectJTBranch(const SDLoc &dl,
   int JTI,
   SelectionDAG &DAG) const {
   const Module *M = DAG.getMachineFunction().getMMI().getModule();
-  Metadata *IsCFProtectionSupported = M->getModuleFlag("cf-protection-branch");
-  if (IsCFProtectionSupported) {
-// In case control-flow branch protection is enabled, we need to add
-// notrack prefix to the indirect branch.
-// In order to do that we create NT_BRIND SDNode.
-// Upon ISEL, the pattern will convert it to jmp with NoTrack prefix.
+
+  uint64_t CFProtectionBranchLevel = 0;
+  if (Metadata *CFProtectionBranchEnabled =
+  M->getModuleFlag("cf-protection-branch"))
+CFProtectionBranchLevel =
+cast(CFProtectionBranchEnabled)
+->getValue()
+->getUniqueInteger()
+.getLimitedValue();
+
+  if (CFProtectionBranchLevel == 1) {
+// In case control-flow branch protection is enabled but we are not
+// protecting jump table branches, we need to add notrack prefix to the
+// indirect branch. In order to do that we create NT_BRIND SDNode. Upon
+// ISEL, the pattern will convert it to jmp with NoTrack prefix.
 SDValue JTInfo = DAG.getJumpTableDebugInfo(JTI, Value, dl);
 return DAG.getNode(X86ISD::NT_BRIND, dl, MVT::Other, JTInfo, Addr);
   }
diff --git a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp 
b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
index 785bdd83cd998b..0710af3af8469a 100644
--- a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
+++ b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
@@ -22,11 +22,13 @@
 #include "llvm/ADT/Statistic.h"