[llvm-branch-commits] [llvm] [PowerPC] Implement paddis (PR #161572)

2025-10-01 Thread Lei Huang via llvm-branch-commits

https://github.com/lei137 updated 
https://github.com/llvm/llvm-project/pull/161572

>From ea6d743c7a6c572053b360fc4eee2dedad681b21 Mon Sep 17 00:00:00 2001
From: Lei Huang 
Date: Tue, 30 Sep 2025 18:09:31 +
Subject: [PATCH 1/2] [PowerPC] Implement paddis

---
 .../Target/PowerPC/AsmParser/PPCAsmParser.cpp |  7 +++
 .../PowerPC/MCTargetDesc/PPCAsmBackend.cpp|  9 
 .../PowerPC/MCTargetDesc/PPCFixupKinds.h  |  6 +++
 .../PowerPC/MCTargetDesc/PPCInstPrinter.cpp   | 12 +
 .../PowerPC/MCTargetDesc/PPCInstPrinter.h |  2 +
 .../PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp |  1 +
 llvm/lib/Target/PowerPC/PPCInstrFuture.td | 44 +++
 llvm/lib/Target/PowerPC/PPCRegisterInfo.td| 19 
 .../PowerPC/ppc-encoding-ISAFuture.txt|  6 +++
 .../PowerPC/ppc64le-encoding-ISAFuture.txt|  6 +++
 llvm/test/MC/PowerPC/ppc-encoding-ISAFuture.s |  8 
 11 files changed, 120 insertions(+)

diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp 
b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index 1fc475dc6cb7e..d09bd9d38d585 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -388,6 +388,13 @@ struct PPCOperand : public MCParsedAsmOperand {
 return Kind == Expression ||
(Kind == Immediate && isInt<34>(getImm()) && (getImm() & 15) == 0);
   }
+
+  bool isS32Imm() const {
+// Once the PC-Rel ABI is finalized, evaluate whether a 32-bit
+// ContextImmediate is needed.
+return Kind == Expression || (Kind == Immediate && isInt<32>(getImm()));
+  }
+
   bool isS34Imm() const {
 // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit
 // ContextImmediate is needed.
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp 
b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
index 04b886ae74993..558351b515a2e 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
@@ -47,6 +47,9 @@ static uint64_t adjustFixupValue(unsigned Kind, uint64_t 
Value) {
   case PPC::fixup_ppc_half16ds:
   case PPC::fixup_ppc_half16dq:
 return Value & 0xfffc;
+  case PPC::fixup_ppc_pcrel32:
+  case PPC::fixup_ppc_imm32:
+return Value & 0x;
   case PPC::fixup_ppc_pcrel34:
   case PPC::fixup_ppc_imm34:
 return Value & 0x3;
@@ -71,6 +74,8 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
   case PPC::fixup_ppc_br24abs:
   case PPC::fixup_ppc_br24_notoc:
 return 4;
+  case PPC::fixup_ppc_pcrel32:
+  case PPC::fixup_ppc_imm32:
   case PPC::fixup_ppc_pcrel34:
   case PPC::fixup_ppc_imm34:
   case FK_Data_8:
@@ -154,6 +159,8 @@ MCFixupKindInfo PPCAsmBackend::getFixupKindInfo(MCFixupKind 
Kind) const {
   {"fixup_ppc_brcond14abs", 16, 14, 0},
   {"fixup_ppc_half16", 0, 16, 0},
   {"fixup_ppc_half16ds", 0, 14, 0},
+  {"fixup_ppc_pcrel32", 0, 32, 0},
+  {"fixup_ppc_imm32", 0, 32, 0},
   {"fixup_ppc_pcrel34", 0, 34, 0},
   {"fixup_ppc_imm34", 0, 34, 0},
   {"fixup_ppc_nofixup", 0, 0, 0}};
@@ -166,6 +173,8 @@ MCFixupKindInfo PPCAsmBackend::getFixupKindInfo(MCFixupKind 
Kind) const {
   {"fixup_ppc_brcond14abs", 2, 14, 0},
   {"fixup_ppc_half16", 0, 16, 0},
   {"fixup_ppc_half16ds", 2, 14, 0},
+  {"fixup_ppc_pcrel32", 0, 32, 0},
+  {"fixup_ppc_imm32", 0, 32, 0},
   {"fixup_ppc_pcrel34", 0, 34, 0},
   {"fixup_ppc_imm34", 0, 34, 0},
   {"fixup_ppc_nofixup", 0, 0, 0}};
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h 
b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
index df0c666f5b113..4164b697649cd 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
@@ -40,6 +40,12 @@ enum Fixups {
   /// instrs like 'std'.
   fixup_ppc_half16ds,
 
+  // A 32-bit fixup corresponding to PC-relative paddis.
+  fixup_ppc_pcrel32,
+
+  // A 32-bit fixup corresponding to Non-PC-relative paddis.
+  fixup_ppc_imm32,
+
   // A 34-bit fixup corresponding to PC-relative paddi.
   fixup_ppc_pcrel34,
 
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp 
b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
index b27bc3bd49315..e2afb9378cbf0 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
@@ -430,6 +430,18 @@ void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, 
unsigned OpNo,
 printOperand(MI, OpNo, STI, O);
 }
 
+void PPCInstPrinter::printS32ImmOperand(const MCInst *MI, unsigned OpNo,
+const MCSubtargetInfo &STI,
+raw_ostream &O) {
+  if (MI->getOperand(OpNo).isImm()) {
+long long Value = MI->getOperand(OpNo).getImm();
+assert(isInt<32>(Value) && "Invalid s32imm argument!");
+O << (long long)Value;
+  }
+  else
+printOperand(MI

[llvm-branch-commits] [clang] release/21.x: [clang-format] Fix bugs in annotating arrows and square… (PR #161052)

2025-10-01 Thread via llvm-branch-commits

https://github.com/dyung closed https://github.com/llvm/llvm-project/pull/161052
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [lldb] release/21.x: [LLDB][ProcessWindows] Set exit status on instance rather than going through all targets (#159308) (PR #161541)

2025-10-01 Thread via llvm-branch-commits

https://github.com/llvmbot milestoned 
https://github.com/llvm/llvm-project/pull/161541
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [lldb] release/21.x: [LLDB][ProcessWindows] Set exit status on instance rather than going through all targets (#159308) (PR #161541)

2025-10-01 Thread via llvm-branch-commits

https://github.com/llvmbot created 
https://github.com/llvm/llvm-project/pull/161541

Backport a868f28c6e9beecb2b3fbe8acfbe0d272fabd14d

Requested by: @Nerixyz

>From 90a7797ad1a4f78bd8c120f8355b39525cd17b79 Mon Sep 17 00:00:00 2001
From: nerix 
Date: Thu, 18 Sep 2025 11:27:25 +0200
Subject: [PATCH] [LLDB][ProcessWindows] Set exit status on instance rather
 than going through all targets (#159308)

When quitting LLDB on Windows while a process was still running, LLDB
would take unusually long to exit. This was due to a temporary deadlock:

The main thread was destroying the processes. In doing so, it iterated
over the target list:

https://github.com/llvm/llvm-project/blob/88c64f76ed2ca226da99b99f60d316b1519fc7d8/lldb/source/Core/Debugger.cpp#L1095-L1098

This locks the list for the whole iteration. Finalizing the process
would eventually lead to `DebuggerThread::StopDebugging`, which
terminates the process and waits for it to exit:

https://github.com/llvm/llvm-project/blob/88c64f76ed2ca226da99b99f60d316b1519fc7d8/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp#L196
The debugger loop (on a separate thread) would see that the process
exited and call
[`ProcessWindows::OnExitProcess`](https://github.com/llvm/llvm-project/blob/88c64f76ed2ca226da99b99f60d316b1519fc7d8/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp#L656-L673).
This calls the static function
[`Process::SetProcessExitStatus`](https://github.com/llvm/llvm-project/blob/0a7a7d56fc882653335beba0d1f8ea9f26089c22/lldb/source/Target/Process.cpp#L1098-L1126).
This tries to find the process by its ID from the debugger's target
list. Doing so requires locking the list, so the debugger thread would
then be stuck on

https://github.com/llvm/llvm-project/blob/0a7a7d56fc882653335beba0d1f8ea9f26089c22/lldb/source/Target/TargetList.cpp#L403

After 5s, the main thread would give up waiting. So every exit where the
process was still running would be delayed by about 5s.

Since `ProcessWindows` would find itself when calling
`SetProcessExitStatus`, we can call `SetExitStatus` directly.

This can also make some tests run faster. For example, the DIA PDB tests
previously took 15s to run on my PC (24 jobs) and now take 5s. For all
shell tests, the difference isn't that big (only about 3s), because most
don't run into this and the tests run in parallel.

(cherry picked from commit a868f28c6e9beecb2b3fbe8acfbe0d272fabd14d)
---
 lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index 27530f032ce51..0fecefe23b88e 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -666,7 +666,7 @@ void ProcessWindows::OnExitProcess(uint32_t exit_code) {
 target->ModulesDidUnload(unloaded_modules, true);
   }
 
-  SetProcessExitStatus(GetID(), true, 0, exit_code);
+  SetExitStatus(exit_code, /*exit_string=*/"");
   SetPrivateState(eStateExited);
 
   ProcessDebugger::OnExitProcess(exit_code);

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


[llvm-branch-commits] [lld] d1e2f89 - [LLD] [COFF] Fix symbol names for import thunks (#160694)

2025-10-01 Thread Douglas Yung via llvm-branch-commits

Author: Martin Storsjö
Date: 2025-10-01T15:13:48Z
New Revision: d1e2f8916128c8c8f402565b0612f6b6e5566702

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

LOG: [LLD] [COFF] Fix symbol names for import thunks (#160694)

9cc9efc483339ece1d52923569bb755db42b69f3 changed LLD to use a
StringTableBuilder for optimizing the string table, used for long
section and symbol names.

That commit had a bug, where the symbol table entry for an import thunk
with a long symbol name wouldn't get fetched from the
StringTableBuilder, if the base symbol name (without the "__imp_"
prefix) wasn't over 8 chars.

This should fix issues with Go, which errors out on reading the
executables with a broken symbol table, as noted in
https://github.com/mstorsjo/llvm-mingw/issues/518 and
https://github.com/golang/go/issues/75219.

(cherry picked from commit 0d6af2db6cd9c964ff300e5b5246c070a57d45e2)

Added: 


Modified: 
lld/COFF/Writer.cpp
lld/test/COFF/strtab.s

Removed: 




diff  --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 076561807af47..ef9d051bf976e 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -1553,7 +1553,7 @@ void Writer::createSymbolAndStringTable() {
 dthunk->wrappedSym->writtenToSymtab = true;
 if (std::optional sym =
 createSymbol(dthunk->wrappedSym)) {
-  if (d->getName().size() > COFF::NameSize)
+  if (dthunk->wrappedSym->getName().size() > COFF::NameSize)
 longNameSymbols.emplace_back(outputSymtab.size(),
  dthunk->wrappedSym->getName());
   outputSymtab.push_back(*sym);

diff  --git a/lld/test/COFF/strtab.s b/lld/test/COFF/strtab.s
index fbdd8df52d540..9edc13e19e825 100644
--- a/lld/test/COFF/strtab.s
+++ b/lld/test/COFF/strtab.s
@@ -1,17 +1,32 @@
 # REQUIRES: x86
 # RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.obj
-# RUN: lld-link -out:%t.exe -entry:main %t.obj -debug:dwarf
+# RUN: lld-link -machine:x64 -def:%S/Inputs/library.def -implib:%t.lib
+# RUN: lld-link -out:%t.exe -entry:main %t.obj %t.lib -debug:dwarf
 # RUN: llvm-readobj --string-table %t.exe | FileCheck %s
+# RUN: llvm-nm %t.exe | FileCheck %s --check-prefix=SYMBOLS
+
+# Note, for this test to have the intended test coverage, the imported symbol
+# "function" needs to be such that the symbol name itself is <= 8 chars, while
+# "__imp_"+name is >8 chars.
 
 # CHECK:  StringTable {
-# CHECK-NEXT:   Length: 87
+# CHECK-NEXT:   Length: 102
 # CHECK-NEXT:   [ 4] .debug_abbrev
 # CHECK-NEXT:   [12] .debug_line
 # CHECK-NEXT:   [1e] long_name_symbolz
 # CHECK-NEXT:   [30] .debug_abbrez
-# CHECK-NEXT:   [3e] __impl_long_name_symbolA
+# CHECK-NEXT:   [3e] __imp_function
+# CHECK-NEXT:   [4d] __impl_long_name_symbolA
 # CHECK-NEXT: }
 
+# SYMBOLS:  140001000 N .debug_abbrez
+# SYMBOLS-NEXT: 140002070 R __imp_function
+# SYMBOLS-NEXT: 140001000 t __impl_long_name_symbolA
+# SYMBOLS-NEXT: 140001010 T function
+# SYMBOLS-NEXT: 140001000 t long_name_symbolA
+# SYMBOLS-NEXT: 140001000 t long_name_symbolz
+# SYMBOLS-NEXT: 140001000 T main
+# SYMBOLS-NEXT: 140001000 t name_symbolA
 
 .global main
 .text
@@ -21,6 +36,7 @@ long_name_symbolA:
 __impl_long_name_symbolA:
 name_symbolA:
 .debug_abbrez:
+  call function
   ret
 
 .section.debug_abbrev,"dr"



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


[llvm-branch-commits] [lld] release/21.x: [LLD] [COFF] Fix symbol names for import thunks (#160694) (PR #160770)

2025-10-01 Thread via llvm-branch-commits

github-actions[bot] wrote:

@mstorsjo (or anyone else). If you would like to add a note about this fix in 
the release notes (completely optional). Please reply to this comment with a 
one or two sentence description of the fix.  When you are done, please add the 
release:note label to this PR. 

https://github.com/llvm/llvm-project/pull/160770
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/21.x: [Mips] Fix atomic min/max generate mips4 instructions when compiling for mips2 (#159717) (PR #160807)

2025-10-01 Thread via llvm-branch-commits

https://github.com/dyung updated 
https://github.com/llvm/llvm-project/pull/160807

>From 559d966bcb54e54d03ff29a2086cbc0f15910683 Mon Sep 17 00:00:00 2001
From: yingopq <[email protected]>
Date: Fri, 26 Sep 2025 11:29:13 +0800
Subject: [PATCH] [Mips] Fix atomic min/max generate mips4 instructions when
 compiling for mips2 (#159717)

Modify instr movn/movz to mixture of beq, move, and sc.

Because atomic-min-max.ll test broken on the expensive builder, I revert
https://github.com/llvm/llvm-project/pull/149983 and resubmit this PR.
The broken reason:
  In i16/i8 function expandAtomicBinOpSubword, we use two successor
after loop2MBB, one does not specify the second parameter, the other
use BranchProbability::getOne() that means 100% probability. This is
contradictory. And the second successor is also specified incorrectly.

The changess:
* llvm/lib/Target/Mips/MipsExpandPseudo.cpp:
  Change loop2MBB`s second successor to correct one and delete the
second parameter BranchProbability::getOne().
* llvm/test/CodeGen/Mips/atomic-min-max.ll:
  Add -verify-machineinstrs option in RUN command;
  Modify i16 test and i8 test according to the changes.

Fix #145411.

(cherry picked from commit 114b3b8b04fe5aae4143e30078637015a9e077ce)
---
 llvm/lib/Target/Mips/MipsExpandPseudo.cpp | 217 +++--
 llvm/test/CodeGen/Mips/atomic-min-max.ll  | 521 ++
 2 files changed, 712 insertions(+), 26 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp 
b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
index 34ff41f6e02da..78f2e5db40f9d 100644
--- a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
+++ b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
@@ -432,13 +432,24 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
   Register OldVal = I->getOperand(6).getReg();
   Register BinOpRes = I->getOperand(7).getReg();
   Register StoreVal = I->getOperand(8).getReg();
+  bool NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4() && !STI->hasMips32();
 
   const BasicBlock *LLVM_BB = BB.getBasicBlock();
   MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
+  MachineBasicBlock *loop1MBB = nullptr;
+  MachineBasicBlock *loop2MBB = nullptr;
+  if (NoMovnInstr) {
+loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
+loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
+  }
   MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
   MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
   MachineFunction::iterator It = ++BB.getIterator();
   MF->insert(It, loopMBB);
+  if (NoMovnInstr) {
+MF->insert(It, loop1MBB);
+MF->insert(It, loop2MBB);
+  }
   MF->insert(It, sinkMBB);
   MF->insert(It, exitMBB);
 
@@ -446,9 +457,19 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
   exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
 
   BB.addSuccessor(loopMBB, BranchProbability::getOne());
-  loopMBB->addSuccessor(sinkMBB);
-  loopMBB->addSuccessor(loopMBB);
-  loopMBB->normalizeSuccProbs();
+  if (NoMovnInstr) {
+loopMBB->addSuccessor(loop1MBB);
+loopMBB->addSuccessor(loop2MBB);
+  } else {
+loopMBB->addSuccessor(sinkMBB);
+loopMBB->addSuccessor(loopMBB);
+loopMBB->normalizeSuccProbs();
+  }
+  if (NoMovnInstr) {
+loop1MBB->addSuccessor(loop2MBB);
+loop2MBB->addSuccessor(loopMBB);
+loop2MBB->addSuccessor(sinkMBB);
+  }
 
   BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
   if (IsNand) {
@@ -525,7 +546,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
   BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
   .addReg(BinOpRes)
   .addReg(Scratch4);
-} else {
+} else if (STI->hasMips4() || STI->hasMips32()) {
   // max: move BinOpRes, StoreVal
   //  movn BinOpRes, Incr, Scratch4, BinOpRes
   // min: move BinOpRes, StoreVal
@@ -537,12 +558,59 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
   .addReg(Incr)
   .addReg(Scratch4)
   .addReg(BinOpRes);
+} else {
+  // if min:
+  // loopMBB:  move BinOpRes, StoreVal
+  //   beq Scratch4, 0, loop1MBB
+  //   j loop2MBB
+  // loop1MBB: move BinOpRes, Incr
+  // loop2MBB: and BinOpRes, BinOpRes, Mask
+  //   and StoreVal, OlddVal, Mask2
+  //   or StoreVal, StoreVal, BinOpRes
+  //   StoreVal = sc StoreVal, 0(Ptr)
+  //   beq StoreVal, zero, loopMBB
+  //
+  // if max:
+  // loopMBB:  move BinOpRes, Incr
+  //   beq Scratch4, 0, loop1MBB
+  //   j loop2MBB
+  // loop1MBB: move BinOpRes, StoreVal
+  // loop2MBB: and BinOpRes, BinOpRes, Mask
+  //   and StoreVal, OlddVal, Mask2
+  //   or StoreVal, StoreVal, BinOpRes
+  //   StoreVal = sc StoreVal, 0(Ptr)
+  //   beq StoreVal, zero, loopMBB
+  if (IsMin) {
+BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
+.addReg(StoreVal)
+.addReg(Mips::ZERO);

[llvm-branch-commits] [llvm] release/21.x: [Mips] Fix atomic min/max generate mips4 instructions when compiling for mips2 (#159717) (PR #160807)

2025-10-01 Thread via llvm-branch-commits

https://github.com/dyung closed https://github.com/llvm/llvm-project/pull/160807
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] 559d966 - [Mips] Fix atomic min/max generate mips4 instructions when compiling for mips2 (#159717)

2025-10-01 Thread Douglas Yung via llvm-branch-commits

Author: yingopq
Date: 2025-10-01T15:15:58Z
New Revision: 559d966bcb54e54d03ff29a2086cbc0f15910683

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

LOG: [Mips] Fix atomic min/max generate mips4 instructions when compiling for 
mips2 (#159717)

Modify instr movn/movz to mixture of beq, move, and sc.

Because atomic-min-max.ll test broken on the expensive builder, I revert
https://github.com/llvm/llvm-project/pull/149983 and resubmit this PR.
The broken reason:
  In i16/i8 function expandAtomicBinOpSubword, we use two successor
after loop2MBB, one does not specify the second parameter, the other
use BranchProbability::getOne() that means 100% probability. This is
contradictory. And the second successor is also specified incorrectly.

The changess:
* llvm/lib/Target/Mips/MipsExpandPseudo.cpp:
  Change loop2MBB`s second successor to correct one and delete the
second parameter BranchProbability::getOne().
* llvm/test/CodeGen/Mips/atomic-min-max.ll:
  Add -verify-machineinstrs option in RUN command;
  Modify i16 test and i8 test according to the changes.

Fix #145411.

(cherry picked from commit 114b3b8b04fe5aae4143e30078637015a9e077ce)

Added: 


Modified: 
llvm/lib/Target/Mips/MipsExpandPseudo.cpp
llvm/test/CodeGen/Mips/atomic-min-max.ll

Removed: 




diff  --git a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp 
b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
index 34ff41f6e02da..78f2e5db40f9d 100644
--- a/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
+++ b/llvm/lib/Target/Mips/MipsExpandPseudo.cpp
@@ -432,13 +432,24 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
   Register OldVal = I->getOperand(6).getReg();
   Register BinOpRes = I->getOperand(7).getReg();
   Register StoreVal = I->getOperand(8).getReg();
+  bool NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4() && !STI->hasMips32();
 
   const BasicBlock *LLVM_BB = BB.getBasicBlock();
   MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
+  MachineBasicBlock *loop1MBB = nullptr;
+  MachineBasicBlock *loop2MBB = nullptr;
+  if (NoMovnInstr) {
+loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
+loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
+  }
   MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
   MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
   MachineFunction::iterator It = ++BB.getIterator();
   MF->insert(It, loopMBB);
+  if (NoMovnInstr) {
+MF->insert(It, loop1MBB);
+MF->insert(It, loop2MBB);
+  }
   MF->insert(It, sinkMBB);
   MF->insert(It, exitMBB);
 
@@ -446,9 +457,19 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
   exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
 
   BB.addSuccessor(loopMBB, BranchProbability::getOne());
-  loopMBB->addSuccessor(sinkMBB);
-  loopMBB->addSuccessor(loopMBB);
-  loopMBB->normalizeSuccProbs();
+  if (NoMovnInstr) {
+loopMBB->addSuccessor(loop1MBB);
+loopMBB->addSuccessor(loop2MBB);
+  } else {
+loopMBB->addSuccessor(sinkMBB);
+loopMBB->addSuccessor(loopMBB);
+loopMBB->normalizeSuccProbs();
+  }
+  if (NoMovnInstr) {
+loop1MBB->addSuccessor(loop2MBB);
+loop2MBB->addSuccessor(loopMBB);
+loop2MBB->addSuccessor(sinkMBB);
+  }
 
   BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
   if (IsNand) {
@@ -525,7 +546,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
   BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
   .addReg(BinOpRes)
   .addReg(Scratch4);
-} else {
+} else if (STI->hasMips4() || STI->hasMips32()) {
   // max: move BinOpRes, StoreVal
   //  movn BinOpRes, Incr, Scratch4, BinOpRes
   // min: move BinOpRes, StoreVal
@@ -537,12 +558,59 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
   .addReg(Incr)
   .addReg(Scratch4)
   .addReg(BinOpRes);
+} else {
+  // if min:
+  // loopMBB:  move BinOpRes, StoreVal
+  //   beq Scratch4, 0, loop1MBB
+  //   j loop2MBB
+  // loop1MBB: move BinOpRes, Incr
+  // loop2MBB: and BinOpRes, BinOpRes, Mask
+  //   and StoreVal, OlddVal, Mask2
+  //   or StoreVal, StoreVal, BinOpRes
+  //   StoreVal = sc StoreVal, 0(Ptr)
+  //   beq StoreVal, zero, loopMBB
+  //
+  // if max:
+  // loopMBB:  move BinOpRes, Incr
+  //   beq Scratch4, 0, loop1MBB
+  //   j loop2MBB
+  // loop1MBB: move BinOpRes, StoreVal
+  // loop2MBB: and BinOpRes, BinOpRes, Mask
+  //   and StoreVal, OlddVal, Mask2
+  //   or StoreVal, StoreVal, BinOpRes
+  //   StoreVal = sc StoreVal, 0(Ptr)
+  //   beq StoreVal, zero, loopMBB
+  if (IsMin) {
+BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
+

[llvm-branch-commits] [llvm] release/21.x: [Mips] Fix atomic min/max generate mips4 instructions when compiling for mips2 (#159717) (PR #160807)

2025-10-01 Thread via llvm-branch-commits

github-actions[bot] wrote:

@brad0 (or anyone else). If you would like to add a note about this fix in the 
release notes (completely optional). Please reply to this comment with a one or 
two sentence description of the fix.  When you are done, please add the 
release:note label to this PR. 

https://github.com/llvm/llvm-project/pull/160807
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] release/21.x: [clang-format] Fix bugs in annotating arrows and square… (PR #161052)

2025-10-01 Thread via llvm-branch-commits

https://github.com/dyung updated 
https://github.com/llvm/llvm-project/pull/161052

>From 41e817a1d1f441494cff32175bae407a9cadd8ee Mon Sep 17 00:00:00 2001
From: owenca 
Date: Sat, 27 Sep 2025 21:29:25 -0700
Subject: [PATCH] release/21.x: [clang-format] Fix bugs in annotating arrows
 and square brackets (#160973)

Backport 4edda3d78c26b9d928d115b2059d0c719eec237b
---
 clang/lib/Format/TokenAnnotator.cpp   |  5 
 clang/lib/Format/UnwrappedLineParser.cpp  | 25 ++-
 clang/unittests/Format/TokenAnnotatorTest.cpp | 14 +++
 3 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index cbeb5ef7e4bf4..580996e870f54 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -829,11 +829,6 @@ class AnnotatingParser {
   if (Parent && Parent->is(TT_PointerOrReference))
 Parent->overwriteFixedType(TT_BinaryOperator);
 }
-// An arrow after an ObjC method expression is not a lambda arrow.
-if (CurrentToken->is(TT_ObjCMethodExpr) && CurrentToken->Next &&
-CurrentToken->Next->is(TT_LambdaArrow)) {
-  CurrentToken->Next->overwriteFixedType(TT_Unknown);
-}
 Left->MatchingParen = CurrentToken;
 CurrentToken->MatchingParen = Left;
 // FirstObjCSelectorName is set when a colon is found. This does
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index 91b8fdc8a3c38..934605733542f 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -2266,7 +2266,7 @@ bool UnwrappedLineParser::tryToParseLambda() {
   if (!tryToParseLambdaIntroducer())
 return false;
 
-  bool SeenArrow = false;
+  FormatToken *Arrow = nullptr;
   bool InTemplateParameterList = false;
 
   while (FormatTok->isNot(tok::l_brace)) {
@@ -2341,17 +2341,13 @@ bool UnwrappedLineParser::tryToParseLambda() {
 case tok::ellipsis:
 case tok::kw_true:
 case tok::kw_false:
-  if (SeenArrow || InTemplateParameterList) {
+  if (Arrow || InTemplateParameterList) {
 nextToken();
 break;
   }
   return true;
 case tok::arrow:
-  // This might or might not actually be a lambda arrow (this could be an
-  // ObjC method invocation followed by a dereferencing arrow). We might
-  // reset this back to TT_Unknown in TokenAnnotator.
-  FormatTok->setFinalizedType(TT_LambdaArrow);
-  SeenArrow = true;
+  Arrow = FormatTok;
   nextToken();
   break;
 case tok::kw_requires: {
@@ -2373,6 +2369,9 @@ bool UnwrappedLineParser::tryToParseLambda() {
   FormatTok->setFinalizedType(TT_LambdaLBrace);
   LSquare.setFinalizedType(TT_LambdaLSquare);
 
+  if (Arrow)
+Arrow->setFinalizedType(TT_LambdaArrow);
+
   NestedLambdas.push_back(Line->SeenDecltypeAuto);
   parseChildBlock();
   assert(!NestedLambdas.empty());
@@ -2386,11 +2385,6 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
   const FormatToken *LeftSquare = FormatTok;
   nextToken();
   if (Previous) {
-if (Previous->Tok.getIdentifierInfo() &&
-!Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
-   tok::kw_co_return)) {
-  return false;
-}
 if (Previous->closesScope()) {
   // Not a potential C-style cast.
   if (Previous->isNot(tok::r_paren))
@@ -2400,6 +2394,13 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
   // and `int (*)()`.
   if (!BeforeRParen || !BeforeRParen->isOneOf(tok::greater, tok::r_paren))
 return false;
+} else if (Previous->is(tok::star)) {
+  Previous = Previous->getPreviousNonComment();
+}
+if (Previous && Previous->Tok.getIdentifierInfo() &&
+!Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
+   tok::kw_co_return)) {
+  return false;
 }
   }
   if (LeftSquare->isCppStructuredBinding(IsCpp))
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp 
b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 0a3dc946e8c1c..259d7e54133a1 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -2229,6 +2229,12 @@ TEST_F(TokenAnnotatorTest, UnderstandsLambdas) {
   ASSERT_EQ(Tokens.size(), 21u) << Tokens;
   EXPECT_TOKEN(Tokens[11], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("SomeFunction({[]() -> int *[] { return {}; }});");
+  ASSERT_EQ(Tokens.size(), 22u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_LambdaDefinitionLParen);
+  EXPECT_TOKEN(Tokens[10], tok::l_square, TT_ArraySubscriptLSquare);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsFunctionAnnotations) {
@@ -4151,6 +4157,14 @@ TEST_F(TokenAnnota

[llvm-branch-commits] [clang] release/21.x: [clang-format] Fix bugs in annotating arrows and square… (PR #161052)

2025-10-01 Thread via llvm-branch-commits

github-actions[bot] wrote:

@owenca (or anyone else). If you would like to add a note about this fix in the 
release notes (completely optional). Please reply to this comment with a one or 
two sentence description of the fix.  When you are done, please add the 
release:note label to this PR. 

https://github.com/llvm/llvm-project/pull/161052
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] release/21.x: [clang][PAC] Don't try to diagnose use of pointer auth on dependent types #159505 (#159859) (PR #161288)

2025-10-01 Thread via llvm-branch-commits

https://github.com/dyung closed https://github.com/llvm/llvm-project/pull/161288
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][SME] Reshuffle emit[prologue|epilogue]() for splitSVEObjects (NFCI) (PR #161217)

2025-10-01 Thread Benjamin Maxwell via llvm-branch-commits

https://github.com/MacDue updated 
https://github.com/llvm/llvm-project/pull/161217

>From 9a5c6811af833840fda0d723cc4f154295ef9f50 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell 
Date: Mon, 29 Sep 2025 15:17:06 +
Subject: [PATCH 1/2] [AArch64][SME] Reshuffle emit[prologue|epilogue]() for
 splitSVEObjects (NFCI)

Requested in 
https://github.com/llvm/llvm-project/pull/142392#discussion_r2207880079

Change-Id: I842faddea1bd54c5e30a9985782baf5dce37e5bb
---
 .../AArch64/AArch64MachineFunctionInfo.h  |   2 +
 .../AArch64/AArch64PrologueEpilogue.cpp   | 285 +-
 2 files changed, 145 insertions(+), 142 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h 
b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
index 4a79d9ce39c8d..00c104ed2254d 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
@@ -481,6 +481,8 @@ class AArch64FunctionInfo final : public 
MachineFunctionInfo {
 StackHazardCSRSlotIndex = Index;
   }
 
+  bool hasSplitSVEObjects() const { return false; }
+
   SMEAttrs getSMEFnAttrs() const { return SMEFnAttrs; }
 
   unsigned getSRetReturnReg() const { return SRetReturnReg; }
diff --git a/llvm/lib/Target/AArch64/AArch64PrologueEpilogue.cpp 
b/llvm/lib/Target/AArch64/AArch64PrologueEpilogue.cpp
index 3de0d4d5ec230..8d648ed0f2cba 100644
--- a/llvm/lib/Target/AArch64/AArch64PrologueEpilogue.cpp
+++ b/llvm/lib/Target/AArch64/AArch64PrologueEpilogue.cpp
@@ -708,8 +708,6 @@ void AArch64PrologueEmitter::emitPrologue() {
   if (AFL.windowsRequiresStackProbe(MF, NumBytes + RealignmentPadding))
 emitWindowsStackProbe(AfterGPRSavesI, DL, NumBytes, RealignmentPadding);
 
-  MachineBasicBlock::iterator CalleeSavesEnd = AfterGPRSavesI;
-
   StackOffset PPRCalleeSavesSize =
   StackOffset::getScalable(AFI->getPPRCalleeSavedStackSize());
   StackOffset ZPRCalleeSavesSize =
@@ -717,76 +715,68 @@ void AArch64PrologueEmitter::emitPrologue() {
   StackOffset SVECalleeSavesSize = PPRCalleeSavesSize + ZPRCalleeSavesSize;
   StackOffset PPRLocalsSize = AFL.getPPRStackSize(MF) - PPRCalleeSavesSize;
   StackOffset ZPRLocalsSize = AFL.getZPRStackSize(MF) - ZPRCalleeSavesSize;
+  std::optional ZPRCalleeSavesBegin,
+  ZPRCalleeSavesEnd, PPRCalleeSavesBegin, PPRCalleeSavesEnd;
 
   StackOffset CFAOffset =
   StackOffset::getFixed((int64_t)MFI.getStackSize() - NumBytes);
   MachineBasicBlock::iterator AfterSVESavesI = AfterGPRSavesI;
-
   if (!FPAfterSVECalleeSaves) {
-MachineBasicBlock::iterator ZPRCalleeSavesBegin = AfterGPRSavesI,
-ZPRCalleeSavesEnd = AfterGPRSavesI;
-MachineBasicBlock::iterator PPRCalleeSavesBegin = AfterGPRSavesI,
-PPRCalleeSavesEnd = AfterGPRSavesI;
-
-// Process the SVE callee-saves to determine what space needs to be
-// allocated.
-
+// Process the SVE callee-saves to find the starts/ends of the ZPR and PPR
+// areas.
+PPRCalleeSavesBegin = AfterGPRSavesI;
 if (PPRCalleeSavesSize) {
   LLVM_DEBUG(dbgs() << "PPRCalleeSavedStackSize = "
 << PPRCalleeSavesSize.getScalable() << "\n");
 
-  PPRCalleeSavesBegin = AfterSVESavesI;
-  assert(isPartOfPPRCalleeSaves(PPRCalleeSavesBegin) &&
+  assert(isPartOfPPRCalleeSaves(*PPRCalleeSavesBegin) &&
  "Unexpected instruction");
   while (isPartOfPPRCalleeSaves(AfterSVESavesI) &&
  AfterSVESavesI != MBB.getFirstTerminator())
 ++AfterSVESavesI;
-  PPRCalleeSavesEnd = AfterSVESavesI;
 }
-
+PPRCalleeSavesEnd = ZPRCalleeSavesBegin = AfterSVESavesI;
 if (ZPRCalleeSavesSize) {
   LLVM_DEBUG(dbgs() << "ZPRCalleeSavedStackSize = "
 << ZPRCalleeSavesSize.getScalable() << "\n");
-  ZPRCalleeSavesBegin = AfterSVESavesI;
-  assert(isPartOfZPRCalleeSaves(ZPRCalleeSavesBegin) &&
+  assert(isPartOfZPRCalleeSaves(*ZPRCalleeSavesBegin) &&
  "Unexpected instruction");
   while (isPartOfZPRCalleeSaves(AfterSVESavesI) &&
  AfterSVESavesI != MBB.getFirstTerminator())
 ++AfterSVESavesI;
-  ZPRCalleeSavesEnd = AfterSVESavesI;
 }
+ZPRCalleeSavesEnd = AfterSVESavesI;
+  }
+
+  if (EmitAsyncCFI)
+emitCalleeSavedSVELocations(AfterSVESavesI);
 
+  if (AFI->hasSplitSVEObjects()) {
+reportFatalInternalError("not implemented yet");
+  } else {
 // Allocate space for the callee saves (if any).
 StackOffset LocalsSize =
 PPRLocalsSize + ZPRLocalsSize + StackOffset::getFixed(NumBytes);
-MachineBasicBlock::iterator CalleeSavesBegin =
-AFI->getPPRCalleeSavedStackSize() ? PPRCalleeSavesBegin
-  : ZPRCalleeSavesBegin;
-allocateStackSpace(CalleeSavesBegin, 0, SVECalleeSavesSize,
-   EmitAsyncCFI && !HasFP, CFAOffset,
-   MFI.hasVarSizedObjects() || LocalsSize);
-
-C

[llvm-branch-commits] [compiler-rt] release/21.x: [compiler-rt][sanitizer] fix msghdr for musl (PR #159551)

2025-10-01 Thread via llvm-branch-commits

https://github.com/dyung updated 
https://github.com/llvm/llvm-project/pull/159551

>From 7da3233cd9822fd0d76ffb32d7684a9bea64d2f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?De=C3=A1k=20Lajos?=
 <[email protected]>
Date: Tue, 22 Jul 2025 20:31:28 +0200
Subject: [PATCH] [compiler-rt][sanitizer] fix msghdr for musl (#136195)

Ran into the issue on Alpine when building with TSAN that
`__sanitizer_msghdr` and the `msghdr` provided by musl did not match.
This caused lots of tsan reports and an eventual termination of the
application by the oom during a `sendmsg`.
---
 .../sanitizer_platform_limits_posix.h | 24 +++
 1 file changed, 24 insertions(+)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h 
b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index f118d53f0df80..24966523f3a02 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -478,6 +478,30 @@ struct __sanitizer_cmsghdr {
   int cmsg_level;
   int cmsg_type;
 };
+#  elif SANITIZER_MUSL
+struct __sanitizer_msghdr {
+  void *msg_name;
+  unsigned msg_namelen;
+  struct __sanitizer_iovec *msg_iov;
+  int msg_iovlen;
+#if SANITIZER_WORDSIZE == 64
+  int __pad1;
+#endif
+  void *msg_control;
+  unsigned msg_controllen;
+#if SANITIZER_WORDSIZE == 64
+  int __pad2;
+#endif
+  int msg_flags;
+};
+struct __sanitizer_cmsghdr {
+  unsigned cmsg_len;
+#if SANITIZER_WORDSIZE == 64
+  int __pad1;
+#endif
+  int cmsg_level;
+  int cmsg_type;
+};
 #  else
 // In POSIX, int msg_iovlen; socklen_t msg_controllen; socklen_t cmsg_len; but
 // many implementations don't conform to the standard.

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


[llvm-branch-commits] [clang] [analyzer] Revert #115918, so empty base class optimization works again (#157480) (PR #160450)

2025-10-01 Thread via llvm-branch-commits

https://github.com/dyung closed https://github.com/llvm/llvm-project/pull/160450
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [IR2Vec] Refactor vocabulary to use section-based storage (PR #158376)

2025-10-01 Thread S. VenkataKeerthy via llvm-branch-commits

https://github.com/svkeerthy updated 
https://github.com/llvm/llvm-project/pull/158376

>From 100c5d4f791440c17041259b30c227fcd57cee43 Mon Sep 17 00:00:00 2001
From: svkeerthy 
Date: Fri, 12 Sep 2025 22:06:44 +
Subject: [PATCH] VocabStorage

---
 llvm/include/llvm/Analysis/IR2Vec.h   | 218 ---
 llvm/lib/Analysis/IR2Vec.cpp  | 256 +++--
 llvm/lib/Analysis/InlineAdvisor.cpp   |   2 +-
 llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp|   6 +-
 .../FunctionPropertiesAnalysisTest.cpp|  13 +-
 llvm/unittests/Analysis/IR2VecTest.cpp| 347 --
 6 files changed, 648 insertions(+), 194 deletions(-)

diff --git a/llvm/include/llvm/Analysis/IR2Vec.h 
b/llvm/include/llvm/Analysis/IR2Vec.h
index f3f9de460218b9..b7c301580a8a4c 100644
--- a/llvm/include/llvm/Analysis/IR2Vec.h
+++ b/llvm/include/llvm/Analysis/IR2Vec.h
@@ -45,6 +45,7 @@
 #include "llvm/Support/JSON.h"
 #include 
 #include 
+#include 
 
 namespace llvm {
 
@@ -144,6 +145,73 @@ struct Embedding {
 using InstEmbeddingsMap = DenseMap;
 using BBEmbeddingsMap = DenseMap;
 
+/// Generic storage class for section-based vocabularies.
+/// VocabStorage provides a generic foundation for storing and accessing
+/// embeddings organized into sections.
+class VocabStorage {
+private:
+  /// Section-based storage
+  std::vector> Sections;
+
+  const size_t TotalSize;
+  const unsigned Dimension;
+
+public:
+  /// Default constructor creates empty storage (invalid state)
+  VocabStorage() : Sections(), TotalSize(0), Dimension(0) {}
+
+  /// Create a VocabStorage with pre-organized section data
+  VocabStorage(std::vector> &&SectionData);
+
+  VocabStorage(VocabStorage &&) = default;
+  VocabStorage &operator=(VocabStorage &&) = delete;
+
+  VocabStorage(const VocabStorage &) = delete;
+  VocabStorage &operator=(const VocabStorage &) = delete;
+
+  /// Get total number of entries across all sections
+  size_t size() const { return TotalSize; }
+
+  /// Get number of sections
+  unsigned getNumSections() const {
+return static_cast(Sections.size());
+  }
+
+  /// Section-based access: Storage[sectionId][localIndex]
+  const std::vector &operator[](unsigned SectionId) const {
+assert(SectionId < Sections.size() && "Invalid section ID");
+return Sections[SectionId];
+  }
+
+  /// Get vocabulary dimension
+  unsigned getDimension() const { return Dimension; }
+
+  /// Check if vocabulary is valid (has data)
+  bool isValid() const { return TotalSize > 0; }
+
+  /// Iterator support for section-based access
+  class const_iterator {
+const VocabStorage *Storage;
+unsigned SectionId = 0;
+size_t LocalIndex = 0;
+
+  public:
+const_iterator(const VocabStorage *Storage, unsigned SectionId,
+   size_t LocalIndex)
+: Storage(Storage), SectionId(SectionId), LocalIndex(LocalIndex) {}
+
+LLVM_ABI const Embedding &operator*() const;
+LLVM_ABI const_iterator &operator++();
+LLVM_ABI bool operator==(const const_iterator &Other) const;
+LLVM_ABI bool operator!=(const const_iterator &Other) const;
+  };
+
+  const_iterator begin() const { return const_iterator(this, 0, 0); }
+  const_iterator end() const {
+return const_iterator(this, getNumSections(), 0);
+  }
+};
+
 /// Class for storing and accessing the IR2Vec vocabulary.
 /// The Vocabulary class manages seed embeddings for LLVM IR entities. The
 /// seed embeddings are the initial learned representations of the entities
@@ -164,7 +232,7 @@ using BBEmbeddingsMap = DenseMap;
 class Vocabulary {
   friend class llvm::IR2VecVocabAnalysis;
 
-  // Vocabulary Slot Layout:
+  // Vocabulary Layout:
   // ++--+
   // | Entity Type| Index Range  |
   // ++--+
@@ -180,8 +248,16 @@ class Vocabulary {
   //   and improves learning. Operands include Comparison predicates
   //   (ICmp/FCmp) along with other operand types. This can be extended to
   //   include other specializations in future.
-  using VocabVector = std::vector;
-  VocabVector Vocab;
+  enum class Section : unsigned {
+Opcodes = 0,
+CanonicalTypes = 1,
+Operands = 2,
+Predicates = 3,
+MaxSections
+  };
+
+  // Use section-based storage for better organization and efficiency
+  VocabStorage Storage;
 
   static constexpr unsigned NumICmpPredicates =
   static_cast(CmpInst::LAST_ICMP_PREDICATE) -
@@ -233,10 +309,23 @@ class Vocabulary {
   NumICmpPredicates + NumFCmpPredicates;
 
   Vocabulary() = default;
-  LLVM_ABI Vocabulary(VocabVector &&Vocab) : Vocab(std::move(Vocab)) {}
+  LLVM_ABI Vocabulary(VocabStorage &&Storage) : Storage(std::move(Storage)) {}
+
+  Vocabulary(const Vocabulary &) = delete;
+  Vocabulary &operator=(const Vocabulary &) = delete;
+
+  Vocabulary(Vocabulary &&) = default;
+  Vocabulary &operator

[llvm-branch-commits] [llvm] [IR2Vec] Refactor vocabulary to use section-based storage (PR #158376)

2025-10-01 Thread S. VenkataKeerthy via llvm-branch-commits

https://github.com/svkeerthy updated 
https://github.com/llvm/llvm-project/pull/158376

>From 100c5d4f791440c17041259b30c227fcd57cee43 Mon Sep 17 00:00:00 2001
From: svkeerthy 
Date: Fri, 12 Sep 2025 22:06:44 +
Subject: [PATCH] VocabStorage

---
 llvm/include/llvm/Analysis/IR2Vec.h   | 218 ---
 llvm/lib/Analysis/IR2Vec.cpp  | 256 +++--
 llvm/lib/Analysis/InlineAdvisor.cpp   |   2 +-
 llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp|   6 +-
 .../FunctionPropertiesAnalysisTest.cpp|  13 +-
 llvm/unittests/Analysis/IR2VecTest.cpp| 347 --
 6 files changed, 648 insertions(+), 194 deletions(-)

diff --git a/llvm/include/llvm/Analysis/IR2Vec.h 
b/llvm/include/llvm/Analysis/IR2Vec.h
index f3f9de460218b9..b7c301580a8a4c 100644
--- a/llvm/include/llvm/Analysis/IR2Vec.h
+++ b/llvm/include/llvm/Analysis/IR2Vec.h
@@ -45,6 +45,7 @@
 #include "llvm/Support/JSON.h"
 #include 
 #include 
+#include 
 
 namespace llvm {
 
@@ -144,6 +145,73 @@ struct Embedding {
 using InstEmbeddingsMap = DenseMap;
 using BBEmbeddingsMap = DenseMap;
 
+/// Generic storage class for section-based vocabularies.
+/// VocabStorage provides a generic foundation for storing and accessing
+/// embeddings organized into sections.
+class VocabStorage {
+private:
+  /// Section-based storage
+  std::vector> Sections;
+
+  const size_t TotalSize;
+  const unsigned Dimension;
+
+public:
+  /// Default constructor creates empty storage (invalid state)
+  VocabStorage() : Sections(), TotalSize(0), Dimension(0) {}
+
+  /// Create a VocabStorage with pre-organized section data
+  VocabStorage(std::vector> &&SectionData);
+
+  VocabStorage(VocabStorage &&) = default;
+  VocabStorage &operator=(VocabStorage &&) = delete;
+
+  VocabStorage(const VocabStorage &) = delete;
+  VocabStorage &operator=(const VocabStorage &) = delete;
+
+  /// Get total number of entries across all sections
+  size_t size() const { return TotalSize; }
+
+  /// Get number of sections
+  unsigned getNumSections() const {
+return static_cast(Sections.size());
+  }
+
+  /// Section-based access: Storage[sectionId][localIndex]
+  const std::vector &operator[](unsigned SectionId) const {
+assert(SectionId < Sections.size() && "Invalid section ID");
+return Sections[SectionId];
+  }
+
+  /// Get vocabulary dimension
+  unsigned getDimension() const { return Dimension; }
+
+  /// Check if vocabulary is valid (has data)
+  bool isValid() const { return TotalSize > 0; }
+
+  /// Iterator support for section-based access
+  class const_iterator {
+const VocabStorage *Storage;
+unsigned SectionId = 0;
+size_t LocalIndex = 0;
+
+  public:
+const_iterator(const VocabStorage *Storage, unsigned SectionId,
+   size_t LocalIndex)
+: Storage(Storage), SectionId(SectionId), LocalIndex(LocalIndex) {}
+
+LLVM_ABI const Embedding &operator*() const;
+LLVM_ABI const_iterator &operator++();
+LLVM_ABI bool operator==(const const_iterator &Other) const;
+LLVM_ABI bool operator!=(const const_iterator &Other) const;
+  };
+
+  const_iterator begin() const { return const_iterator(this, 0, 0); }
+  const_iterator end() const {
+return const_iterator(this, getNumSections(), 0);
+  }
+};
+
 /// Class for storing and accessing the IR2Vec vocabulary.
 /// The Vocabulary class manages seed embeddings for LLVM IR entities. The
 /// seed embeddings are the initial learned representations of the entities
@@ -164,7 +232,7 @@ using BBEmbeddingsMap = DenseMap;
 class Vocabulary {
   friend class llvm::IR2VecVocabAnalysis;
 
-  // Vocabulary Slot Layout:
+  // Vocabulary Layout:
   // ++--+
   // | Entity Type| Index Range  |
   // ++--+
@@ -180,8 +248,16 @@ class Vocabulary {
   //   and improves learning. Operands include Comparison predicates
   //   (ICmp/FCmp) along with other operand types. This can be extended to
   //   include other specializations in future.
-  using VocabVector = std::vector;
-  VocabVector Vocab;
+  enum class Section : unsigned {
+Opcodes = 0,
+CanonicalTypes = 1,
+Operands = 2,
+Predicates = 3,
+MaxSections
+  };
+
+  // Use section-based storage for better organization and efficiency
+  VocabStorage Storage;
 
   static constexpr unsigned NumICmpPredicates =
   static_cast(CmpInst::LAST_ICMP_PREDICATE) -
@@ -233,10 +309,23 @@ class Vocabulary {
   NumICmpPredicates + NumFCmpPredicates;
 
   Vocabulary() = default;
-  LLVM_ABI Vocabulary(VocabVector &&Vocab) : Vocab(std::move(Vocab)) {}
+  LLVM_ABI Vocabulary(VocabStorage &&Storage) : Storage(std::move(Storage)) {}
+
+  Vocabulary(const Vocabulary &) = delete;
+  Vocabulary &operator=(const Vocabulary &) = delete;
+
+  Vocabulary(Vocabulary &&) = default;
+  Vocabulary &operator

[llvm-branch-commits] [llvm] [AArch64][SME] Support split ZPR and PPR area allocation (PR #142392)

2025-10-01 Thread Sander de Smalen via llvm-branch-commits


@@ -1,6 +1,7 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 
UTC_ARGS: --version 5
 # RUN: llc -mtriple=aarch64-linux-gnu -aarch64-enable-zpr-predicate-spills 
-run-pass=greedy %s -o - | FileCheck %s
 # RUN: llc -mtriple=aarch64-linux-gnu -aarch64-enable-zpr-predicate-spills 
-start-before=greedy -stop-after=aarch64-expand-pseudo -verify-machineinstrs %s 
-o - | FileCheck %s --check-prefix=EXPAND
+

sdesmalen-arm wrote:

nit: unnecessary whitespace.

https://github.com/llvm/llvm-project/pull/142392
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][SME] Support split ZPR and PPR area allocation (PR #142392)

2025-10-01 Thread Sander de Smalen via llvm-branch-commits


@@ -4376,8 +4625,7 @@ static bool getSVECalleeSaveSlotRange(const 
MachineFrameInfo &MFI,
 }
 
 static SVEStackSizes determineSVEStackSizes(MachineFunction &MF,
-AssignObjectOffsets AssignOffsets,
-bool SplitSVEObjects) {
+AssignObjectOffsets AssignOffsets) 
{

sdesmalen-arm wrote:

Yeah, that comment was outdated.

https://github.com/llvm/llvm-project/pull/142392
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [IR2Vec] Initial infrastructure for MIR2Vec (PR #161463)

2025-10-01 Thread Mircea Trofin via llvm-branch-commits


@@ -0,0 +1,325 @@
+//===- MIR2Vec.cpp - Implementation of MIR2Vec ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
+// Exceptions. See the LICENSE file for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+/// \file
+/// This file implements the MIR2Vec algorithm for Machine IR embeddings.
+///
+//===--===//
+
+#include "llvm/CodeGen/MIR2Vec.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Regex.h"
+
+using namespace llvm;
+using namespace mir2vec;
+
+#define DEBUG_TYPE "mir2vec"
+
+STATISTIC(MIRVocabMissCounter,
+  "Number of lookups to MIR entities not present in the vocabulary");
+
+namespace llvm {
+namespace mir2vec {
+cl::OptionCategory MIR2VecCategory("MIR2Vec Options");
+
+// FIXME: Use a default vocab when not specified
+static cl::opt
+VocabFile("mir2vec-vocab-path", cl::Optional,
+  cl::desc("Path to the vocabulary file for MIR2Vec"), 
cl::init(""),
+  cl::cat(MIR2VecCategory));
+cl::opt OpcWeight("mir2vec-opc-weight", cl::Optional, cl::init(1.0),
+ cl::desc("Weight for machine opcode embeddings"),
+ cl::cat(MIR2VecCategory));
+} // namespace mir2vec
+} // namespace llvm
+
+//===--===//
+// Vocabulary Implementation
+//===--===//
+
+Vocabulary::Vocabulary(VocabMap &&OpcodeEntries, const TargetInstrInfo *TII) {
+  // Early return for invalid inputs - creates empty/invalid vocabulary

mtrofin wrote:

instead of `isValid` we could have a static `create` returning a 
`std::optional`? or this follows the existing pattern in IR2Vec

https://github.com/llvm/llvm-project/pull/161463
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [PowerPC] Implement paddis (PR #161572)

2025-10-01 Thread via llvm-branch-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff origin/main HEAD --extensions cpp,h -- 
llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp 
llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp 
llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h 
llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp 
llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h 
llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
``

:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:





View the diff from clang-format here.


``diff
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp 
b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
index e2afb9378..acbc39f3e 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
@@ -437,8 +437,7 @@ void PPCInstPrinter::printS32ImmOperand(const MCInst *MI, 
unsigned OpNo,
 long long Value = MI->getOperand(OpNo).getImm();
 assert(isInt<32>(Value) && "Invalid s32imm argument!");
 O << (long long)Value;
-  }
-  else
+  } else
 printOperand(MI, OpNo, STI, O);
 }
 

``




https://github.com/llvm/llvm-project/pull/161572
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [IR2Vec] Initial infrastructure for MIR2Vec (PR #161463)

2025-10-01 Thread S. VenkataKeerthy via llvm-branch-commits


@@ -329,6 +329,43 @@ bool VocabStorage::const_iterator::operator!=(
   return !(*this == Other);
 }
 
+Error VocabStorage::parseVocabSection(StringRef Key,
+  const json::Value &ParsedVocabValue,
+  VocabMap &TargetVocab, unsigned &Dim) {
+  json::Path::Root Path("");

svkeerthy wrote:

That's what I am trying to do.. moving it to VocabStorage can help us use this 
method in both IR and MIR vocabulary. (Will push it as a separate NFC as you 
mentioned in earlier comment)

https://github.com/llvm/llvm-project/pull/161463
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] release/21.x: [NVPTX] Disable relative lookup tables (#159748) (PR #160064)

2025-10-01 Thread via llvm-branch-commits

https://github.com/dyung updated 
https://github.com/llvm/llvm-project/pull/160064

>From 31e4363ba9c2e0582a2b1105fe24dbfff860b7f6 Mon Sep 17 00:00:00 2001
From: Nikita Popov 
Date: Mon, 22 Sep 2025 12:18:25 +0200
Subject: [PATCH] [NVPTX] Disable relative lookup tables (#159748)

Relative lookup tables result in "LLVM ERROR: Circular dependency found
in global variable set", so disable them for this target.

(cherry picked from commit 1ed15374638ecf6046169194b4b3ca34b7cf340f)
---
 .../Target/NVPTX/NVPTXTargetTransformInfo.h   |  5 +++
 .../RelLookupTableConverter/nvptx.ll  | 32 +++
 2 files changed, 37 insertions(+)
 create mode 100644 llvm/test/Transforms/RelLookupTableConverter/nvptx.ll

diff --git a/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h 
b/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h
index 9a6e261c811a0..437edfb8ffc75 100644
--- a/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h
+++ b/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h
@@ -183,6 +183,11 @@ class NVPTXTTIImpl final : public 
BasicTTIImplBase {
   void collectKernelLaunchBounds(
   const Function &F,
   SmallVectorImpl> &LB) const override;
+
+  bool shouldBuildRelLookupTables() const override {
+// Self-referential globals are not supported.
+return false;
+  }
 };
 
 } // end namespace llvm
diff --git a/llvm/test/Transforms/RelLookupTableConverter/nvptx.ll 
b/llvm/test/Transforms/RelLookupTableConverter/nvptx.ll
new file mode 100644
index 0..70ebf220c369c
--- /dev/null
+++ b/llvm/test/Transforms/RelLookupTableConverter/nvptx.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --check-globals all --version 5
+; RUN: opt < %s -passes=rel-lookup-table-converter -relocation-model=pic -S | 
FileCheck %s
+; REQUIRES: nvptx-registered-target
+target triple = "nvptx64-nvidia-cuda"
+
+; Do not produce relative lookup table for nvptx target.
+
+@a1 = internal constant i32 0, align 4
+@b1 = internal constant i32 0, align 4
+@c1 = internal constant i32 0, align 4
+@d1 = internal constant i32 0, align 4
+
[email protected] = private unnamed_addr constant [3 x ptr] [ptr @a1, ptr @b1, ptr 
@c1], align 8
+
+;.
+; CHECK: @a1 = internal constant i32 0, align 4
+; CHECK: @b1 = internal constant i32 0, align 4
+; CHECK: @c1 = internal constant i32 0, align 4
+; CHECK: @d1 = internal constant i32 0, align 4
+; CHECK: @switch.table = private unnamed_addr constant [3 x ptr] [ptr @a1, ptr 
@b1, ptr @c1], align 8
+;.
+define ptr @internal_linkage(i32 %cond) {
+; CHECK-LABEL: define ptr @internal_linkage(
+; CHECK-SAME: i32 [[COND:%.*]]) {
+; CHECK-NEXT:[[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x ptr], ptr 
@switch.table, i32 0, i32 [[COND]]
+; CHECK-NEXT:[[RELTABLE_INTRINSIC:%.*]] = load ptr, ptr [[SWITCH_GEP]], 
align 8
+; CHECK-NEXT:ret ptr [[RELTABLE_INTRINSIC]]
+;
+  %switch.gep = getelementptr inbounds [3 x ptr], ptr @switch.table, i32 0, 
i32 %cond
+  %switch.load = load ptr, ptr %switch.gep, align 8
+  ret ptr %switch.load
+}

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


[llvm-branch-commits] [llvm] 31e4363 - [NVPTX] Disable relative lookup tables (#159748)

2025-10-01 Thread Douglas Yung via llvm-branch-commits

Author: Nikita Popov
Date: 2025-10-01T14:31:21Z
New Revision: 31e4363ba9c2e0582a2b1105fe24dbfff860b7f6

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

LOG: [NVPTX] Disable relative lookup tables (#159748)

Relative lookup tables result in "LLVM ERROR: Circular dependency found
in global variable set", so disable them for this target.

(cherry picked from commit 1ed15374638ecf6046169194b4b3ca34b7cf340f)

Added: 
llvm/test/Transforms/RelLookupTableConverter/nvptx.ll

Modified: 
llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h

Removed: 




diff  --git a/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h 
b/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h
index 9a6e261c811a0..437edfb8ffc75 100644
--- a/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h
+++ b/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h
@@ -183,6 +183,11 @@ class NVPTXTTIImpl final : public 
BasicTTIImplBase {
   void collectKernelLaunchBounds(
   const Function &F,
   SmallVectorImpl> &LB) const override;
+
+  bool shouldBuildRelLookupTables() const override {
+// Self-referential globals are not supported.
+return false;
+  }
 };
 
 } // end namespace llvm

diff  --git a/llvm/test/Transforms/RelLookupTableConverter/nvptx.ll 
b/llvm/test/Transforms/RelLookupTableConverter/nvptx.ll
new file mode 100644
index 0..70ebf220c369c
--- /dev/null
+++ b/llvm/test/Transforms/RelLookupTableConverter/nvptx.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --check-globals all --version 5
+; RUN: opt < %s -passes=rel-lookup-table-converter -relocation-model=pic -S | 
FileCheck %s
+; REQUIRES: nvptx-registered-target
+target triple = "nvptx64-nvidia-cuda"
+
+; Do not produce relative lookup table for nvptx target.
+
+@a1 = internal constant i32 0, align 4
+@b1 = internal constant i32 0, align 4
+@c1 = internal constant i32 0, align 4
+@d1 = internal constant i32 0, align 4
+
[email protected] = private unnamed_addr constant [3 x ptr] [ptr @a1, ptr @b1, ptr 
@c1], align 8
+
+;.
+; CHECK: @a1 = internal constant i32 0, align 4
+; CHECK: @b1 = internal constant i32 0, align 4
+; CHECK: @c1 = internal constant i32 0, align 4
+; CHECK: @d1 = internal constant i32 0, align 4
+; CHECK: @switch.table = private unnamed_addr constant [3 x ptr] [ptr @a1, ptr 
@b1, ptr @c1], align 8
+;.
+define ptr @internal_linkage(i32 %cond) {
+; CHECK-LABEL: define ptr @internal_linkage(
+; CHECK-SAME: i32 [[COND:%.*]]) {
+; CHECK-NEXT:[[SWITCH_GEP:%.*]] = getelementptr inbounds [3 x ptr], ptr 
@switch.table, i32 0, i32 [[COND]]
+; CHECK-NEXT:[[RELTABLE_INTRINSIC:%.*]] = load ptr, ptr [[SWITCH_GEP]], 
align 8
+; CHECK-NEXT:ret ptr [[RELTABLE_INTRINSIC]]
+;
+  %switch.gep = getelementptr inbounds [3 x ptr], ptr @switch.table, i32 0, 
i32 %cond
+  %switch.load = load ptr, ptr %switch.gep, align 8
+  ret ptr %switch.load
+}



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


[llvm-branch-commits] [clang] 0060034 - [analyzer] Revert #115918, so empty base class optimization works again (#157480)

2025-10-01 Thread Douglas Yung via llvm-branch-commits

Author: Balazs Benics
Date: 2025-10-01T15:10:18Z
New Revision: 0060034c6a0b3735c3f7fd89173884a10fe30206

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

LOG: [analyzer] Revert #115918, so empty base class optimization works again 
(#157480)

Tldr;
We can't unconditionally trivially copy empty classes because that would
clobber the stored entries in the object that the optimized empty class
overlaps with.

This regression was introduced by #115918, which introduced other
clobbering issues, like the handling of `[[no_unique_address]]` fields
in #137252.

Read issue #157467 for the detailed explanation, but in short, I'd
propose reverting the original patch because these was a lot of problems
with it for arguably not much gain.
In particular, that patch was motivated by unifying the handling of
classes so that copy events would be triggered for a class no matter if
it had data members or not.
So in hindsight, it was not worth it.

I plan to backport this to clang-21 as well, and mention in the release
notes that this should fix the regression from clang-20.

PS: Also an interesting read [D43714](https://reviews.llvm.org/D43714)
in hindsight.

Fixes #157467
CPP-6574

(cherry picked from commit 38b948bd4b9bd0ed532c3bea69e0038b3dffe80a)

Added: 
clang/test/Analysis/issue-157467.cpp

Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
clang/test/Analysis/ctor-trivial-copy.cpp
clang/test/Analysis/taint-generic.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f03a3273c4518..43529b0f28c3d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1261,6 +1261,11 @@ New features
 Crash and bug fixes
 ^^^
 
+- Fixed a regression introduced by clang-20 in #GH115918 that lead to false
+  positive reports when ``[[no_unique_address]]`` or empty base class
+  optimization techniques were used. Most notably, some ``std::unique_ptr``
+  implementations. (#GH157467)
+
 - Fixed a crash when C++20 parenthesized initializer lists are used.
   This affected a crash of the well-known lambda overloaded pattern.
   (#GH136041, #GH135665)

diff  --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 85353848aa124..dc715c7d46d8b 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -71,21 +71,30 @@ void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, 
ExplodedNode *Pred,
   Bldr.takeNodes(Pred);
 
   assert(ThisRD);
-  SVal V = Call.getArgSVal(0);
-  const Expr *VExpr = Call.getArgExpr(0);
 
-  // If the value being copied is not unknown, load from its location to get
-  // an aggregate rvalue.
-  if (std::optional L = V.getAs())
-V = Pred->getState()->getSVal(*L);
-  else
-assert(V.isUnknownOrUndef());
+  if (!ThisRD->isEmpty()) {
+SVal V = Call.getArgSVal(0);
+const Expr *VExpr = Call.getArgExpr(0);
 
-  ExplodedNodeSet Tmp;
-  evalLocation(Tmp, CallExpr, VExpr, Pred, Pred->getState(), V,
-   /*isLoad=*/true);
-  for (ExplodedNode *N : Tmp)
-evalBind(Dst, CallExpr, N, ThisVal, V, true);
+// If the value being copied is not unknown, load from its location to get
+// an aggregate rvalue.
+if (std::optional L = V.getAs())
+  V = Pred->getState()->getSVal(*L);
+else
+  assert(V.isUnknownOrUndef());
+
+ExplodedNodeSet Tmp;
+evalLocation(Tmp, CallExpr, VExpr, Pred, Pred->getState(), V,
+ /*isLoad=*/true);
+for (ExplodedNode *N : Tmp)
+  evalBind(Dst, CallExpr, N, ThisVal, V, true);
+  } else {
+// We can't copy empty classes because of empty base class optimization.
+// In that case, copying the empty base class subobject would overwrite the
+// object that it overlaps with - so let's not do that.
+// See issue-157467.cpp for an example.
+Dst.Add(Pred);
+  }
 
   PostStmt PS(CallExpr, LCtx);
   for (ExplodedNode *N : Dst) {

diff  --git a/clang/test/Analysis/ctor-trivial-copy.cpp 
b/clang/test/Analysis/ctor-trivial-copy.cpp
index 45c8ca4c51776..940ff9ba3ed9c 100644
--- a/clang/test/Analysis/ctor-trivial-copy.cpp
+++ b/clang/test/Analysis/ctor-trivial-copy.cpp
@@ -46,15 +46,10 @@ void _01_empty_structs() {
   empty Empty = conjure();
   empty Empty2 = Empty;
   empty Empty3 = Empty2;
-  // All of these should refer to the exact same symbol, because all of
-  // these trivial copies refer to the original conjured value.
-  // There were Unknown before:
-  clang_analyzer_denote(Empty, "$Empty");
-  clang_analyzer_express(Empty);  // expected-warning {{$Empty}}
-  clang_analyzer_express(Empty2); // expected-warning {{$Empty}}
-  clang_analyzer_express(Empt

[llvm-branch-commits] [clang] release/21.x: [clang][PAC] Don't try to diagnose use of pointer auth on dependent types #159505 (#159859) (PR #161288)

2025-10-01 Thread Oliver Hunt via llvm-branch-commits

ojhunt wrote:

> @ojhunt (or anyone else). If you would like to add a note about this fix in 
> the release notes (completely optional). Please reply to this comment with a 
> one or two sentence description of the fix. When you are done, please add the 
> release:note label to this PR.

Fix error when performing bitwise layout queries of uninstantiated template 
types containing pointer authenticated fields and bases.

https://github.com/llvm/llvm-project/pull/161288
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][SME] Support split ZPR and PPR area allocation (PR #142392)

2025-10-01 Thread Sander de Smalen via llvm-branch-commits

https://github.com/sdesmalen-arm edited 
https://github.com/llvm/llvm-project/pull/142392
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [SimplifyCFG][profcheck] Synthesize profile for `br (X == 0 | X == 1), T, F1 -> switch (PR #161549)

2025-10-01 Thread Mircea Trofin via llvm-branch-commits

https://github.com/mtrofin created 
https://github.com/llvm/llvm-project/pull/161549

None

>From 485a8ffed0be28fa5a6852c63ede86615e439342 Mon Sep 17 00:00:00 2001
From: Mircea Trofin 
Date: Tue, 30 Sep 2025 16:21:27 -0700
Subject: [PATCH] [SimplifyCFG][profcheck] Synthesize profile for `br (X == 0 |
 X == 1), T, F1 -> switch

---
 llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 30 ++-
 .../Transforms/SimplifyCFG/switch_create.ll   | 27 -
 2 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp 
b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 4d1f768e2177a..df436d0f68028 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -5148,14 +5148,18 @@ bool 
SimplifyCFGOpt::simplifyBranchOnICmpChain(BranchInst *BI,
   if (ExtraCase && Values.size() < 2)
 return false;
 
-  // TODO: Preserve branch weight metadata, similarly to how
-  // foldValueComparisonIntoPredecessors preserves it.
+  SmallVector BranchWeights;
+  const bool HasProfile = !ProfcheckDisableMetadataFixes &&
+  extractBranchWeights(*BI, BranchWeights);
 
   // Figure out which block is which destination.
   BasicBlock *DefaultBB = BI->getSuccessor(1);
   BasicBlock *EdgeBB = BI->getSuccessor(0);
-  if (!TrueWhenEqual)
+  if (!TrueWhenEqual) {
 std::swap(DefaultBB, EdgeBB);
+if (HasProfile)
+  std::swap(BranchWeights[0], BranchWeights[1]);
+  }
 
   BasicBlock *BB = BI->getParent();
 
@@ -5186,10 +5190,11 @@ bool 
SimplifyCFGOpt::simplifyBranchOnICmpChain(BranchInst *BI,
 if (!isGuaranteedNotToBeUndefOrPoison(ExtraCase, AC, BI, nullptr))
   ExtraCase = Builder.CreateFreeze(ExtraCase);
 
-if (TrueWhenEqual)
-  Builder.CreateCondBr(ExtraCase, EdgeBB, NewBB);
-else
-  Builder.CreateCondBr(ExtraCase, NewBB, EdgeBB);
+// We don't have any info about this condition.
+auto *Br = TrueWhenEqual ? Builder.CreateCondBr(ExtraCase, EdgeBB, NewBB)
+ : Builder.CreateCondBr(ExtraCase, NewBB, EdgeBB);
+setExplicitlyUnknownBranchWeightsIfProfiled(*Br, *NewBB->getParent(),
+DEBUG_TYPE);
 
 OldTI->eraseFromParent();
 
@@ -5216,6 +5221,17 @@ bool 
SimplifyCFGOpt::simplifyBranchOnICmpChain(BranchInst *BI,
 
   // Create the new switch instruction now.
   SwitchInst *New = Builder.CreateSwitch(CompVal, DefaultBB, Values.size());
+  if (HasProfile) {
+// We know the weight of the default case. We don't know the weight of the
+// other cases, but rather than completely loose profiling info, we split
+// the remaining probability equally over them.
+SmallVector NewWeights(Values.size() + 1);
+NewWeights[0] = BranchWeights[1]; // this is the default, and we swapped if
+  // TrueWhenEqual.
+for (auto &V : drop_begin(NewWeights))
+  V = BranchWeights[0] / Values.size();
+setBranchWeights(*New, NewWeights, /*IsExpected=*/false);
+  }
 
   // Add all of the 'cases' to the switch instruction.
   for (ConstantInt *Val : Values)
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create.ll 
b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
index 18c4ade46162c..ef5aee68e268e 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_create.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --check-globals
 ; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 
-switch-range-to-icmp < %s | FileCheck %s
 ; RUN: opt -S -data-layout="p:32:32-p1:16:16" -passes=simplifycfg 
-simplifycfg-require-and-preserve-domtree=1 -switch-range-to-icmp < %s | 
FileCheck -check-prefix=CHECK -check-prefix=DL %s
 
@@ -6,12 +6,12 @@ declare void @foo1()
 
 declare void @foo2()
 
-define void @test1(i32 %V) {
+define void @test1(i32 %V) !prof !0 {
 ; CHECK-LABEL: @test1(
 ; CHECK-NEXT:switch i32 [[V:%.*]], label [[F:%.*]] [
 ; CHECK-NEXT:  i32 17, label [[T:%.*]]
 ; CHECK-NEXT:  i32 4, label [[T]]
-; CHECK-NEXT:]
+; CHECK-NEXT:], !prof [[PROF1:![0-9]+]]
 ; CHECK:   common.ret:
 ; CHECK-NEXT:ret void
 ; CHECK:   T:
@@ -24,7 +24,7 @@ define void @test1(i32 %V) {
   %C1 = icmp eq i32 %V, 4 ;  [#uses=1]
   %C2 = icmp eq i32 %V, 17;  [#uses=1]
   %CN = or i1 %C1, %C2;  [#uses=1]
-  br i1 %CN, label %T, label %F
+  br i1 %CN, label %T, label %F, !prof !1
 T:  ; preds = %0
   call void @foo1( )
   ret void
@@ -116,12 +116,12 @@ F:  ; preds = %0
   ret void
 }
 
-define void @test2(i32 %V) {
+define void @test2(i32 %V) !prof !0 {
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:switch i32 [[V:%.*]], label [[T:%.*]] [
 ; CHECK-NEXT:  i32 17, label [[F:%.*]]
 ; CHECK-NEXT:

[llvm-branch-commits] [llvm] [SimplifyCFG][profcheck] Synthesize profile for `br (X == 0 | X == 1), T, F1 -> switch (PR #161549)

2025-10-01 Thread Mircea Trofin via llvm-branch-commits

mtrofin wrote:

> [!WARNING]
> This pull request is not mergeable via GitHub because a downstack PR is 
> open. Once all requirements are satisfied, merge this PR as a stack  href="https://app.graphite.dev/github/pr/llvm/llvm-project/161549?utm_source=stack-comment-downstack-mergeability-warning";
>  >on Graphite.
> https://graphite.dev/docs/merge-pull-requests";>Learn more

* **#161549** https://app.graphite.dev/github/pr/llvm/llvm-project/161549?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/161549?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#160629** https://app.graphite.dev/github/pr/llvm/llvm-project/160629?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#159645** https://app.graphite.dev/github/pr/llvm/llvm-project/159645?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#159644** https://app.graphite.dev/github/pr/llvm/llvm-project/159644?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn 
more about https://stacking.dev/?utm_source=stack-comment";>stacking.


https://github.com/llvm/llvm-project/pull/161549
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] 41e817a - release/21.x: [clang-format] Fix bugs in annotating arrows and square brackets (#160973)

2025-10-01 Thread Douglas Yung via llvm-branch-commits

Author: owenca
Date: 2025-10-01T15:17:16Z
New Revision: 41e817a1d1f441494cff32175bae407a9cadd8ee

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

LOG: release/21.x: [clang-format] Fix bugs in annotating arrows and square 
brackets (#160973)

Backport 4edda3d78c26b9d928d115b2059d0c719eec237b

Added: 


Modified: 
clang/lib/Format/TokenAnnotator.cpp
clang/lib/Format/UnwrappedLineParser.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp

Removed: 




diff  --git a/clang/lib/Format/TokenAnnotator.cpp 
b/clang/lib/Format/TokenAnnotator.cpp
index cbeb5ef7e4bf4..580996e870f54 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -829,11 +829,6 @@ class AnnotatingParser {
   if (Parent && Parent->is(TT_PointerOrReference))
 Parent->overwriteFixedType(TT_BinaryOperator);
 }
-// An arrow after an ObjC method expression is not a lambda arrow.
-if (CurrentToken->is(TT_ObjCMethodExpr) && CurrentToken->Next &&
-CurrentToken->Next->is(TT_LambdaArrow)) {
-  CurrentToken->Next->overwriteFixedType(TT_Unknown);
-}
 Left->MatchingParen = CurrentToken;
 CurrentToken->MatchingParen = Left;
 // FirstObjCSelectorName is set when a colon is found. This does

diff  --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index 91b8fdc8a3c38..934605733542f 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -2266,7 +2266,7 @@ bool UnwrappedLineParser::tryToParseLambda() {
   if (!tryToParseLambdaIntroducer())
 return false;
 
-  bool SeenArrow = false;
+  FormatToken *Arrow = nullptr;
   bool InTemplateParameterList = false;
 
   while (FormatTok->isNot(tok::l_brace)) {
@@ -2341,17 +2341,13 @@ bool UnwrappedLineParser::tryToParseLambda() {
 case tok::ellipsis:
 case tok::kw_true:
 case tok::kw_false:
-  if (SeenArrow || InTemplateParameterList) {
+  if (Arrow || InTemplateParameterList) {
 nextToken();
 break;
   }
   return true;
 case tok::arrow:
-  // This might or might not actually be a lambda arrow (this could be an
-  // ObjC method invocation followed by a dereferencing arrow). We might
-  // reset this back to TT_Unknown in TokenAnnotator.
-  FormatTok->setFinalizedType(TT_LambdaArrow);
-  SeenArrow = true;
+  Arrow = FormatTok;
   nextToken();
   break;
 case tok::kw_requires: {
@@ -2373,6 +2369,9 @@ bool UnwrappedLineParser::tryToParseLambda() {
   FormatTok->setFinalizedType(TT_LambdaLBrace);
   LSquare.setFinalizedType(TT_LambdaLSquare);
 
+  if (Arrow)
+Arrow->setFinalizedType(TT_LambdaArrow);
+
   NestedLambdas.push_back(Line->SeenDecltypeAuto);
   parseChildBlock();
   assert(!NestedLambdas.empty());
@@ -2386,11 +2385,6 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
   const FormatToken *LeftSquare = FormatTok;
   nextToken();
   if (Previous) {
-if (Previous->Tok.getIdentifierInfo() &&
-!Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
-   tok::kw_co_return)) {
-  return false;
-}
 if (Previous->closesScope()) {
   // Not a potential C-style cast.
   if (Previous->isNot(tok::r_paren))
@@ -2400,6 +2394,13 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
   // and `int (*)()`.
   if (!BeforeRParen || !BeforeRParen->isOneOf(tok::greater, tok::r_paren))
 return false;
+} else if (Previous->is(tok::star)) {
+  Previous = Previous->getPreviousNonComment();
+}
+if (Previous && Previous->Tok.getIdentifierInfo() &&
+!Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
+   tok::kw_co_return)) {
+  return false;
 }
   }
   if (LeftSquare->isCppStructuredBinding(IsCpp))

diff  --git a/clang/unittests/Format/TokenAnnotatorTest.cpp 
b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 0a3dc946e8c1c..259d7e54133a1 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -2229,6 +2229,12 @@ TEST_F(TokenAnnotatorTest, UnderstandsLambdas) {
   ASSERT_EQ(Tokens.size(), 21u) << Tokens;
   EXPECT_TOKEN(Tokens[11], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("SomeFunction({[]() -> int *[] { return {}; }});");
+  ASSERT_EQ(Tokens.size(), 22u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_LambdaDefinitionLParen);
+  EXPECT_TOKEN(Tokens[10], tok::l_square, TT_ArraySubscriptLSquare);
 }
 
 TEST_F(TokenAnnotato

[llvm-branch-commits] [clang] port 5b4819e to release (PR #159209)

2025-10-01 Thread via llvm-branch-commits

https://github.com/dyung updated 
https://github.com/llvm/llvm-project/pull/159209

>From 4e9d1b69a64c0d4f71b2c7939f043353730d2bbb Mon Sep 17 00:00:00 2001
From: David Blaikie 
Date: Tue, 16 Sep 2025 22:42:55 +
Subject: [PATCH] Port 5b4819e to release/21.x

Fix for the port of 665e875 to release/21.x in PR156664
---
 clang/test/CodeGenCXX/debug-info-structured-binding.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CodeGenCXX/debug-info-structured-binding.cpp 
b/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
index 4a4a4d8bdfaad..8032ce85c9e25 100644
--- a/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
+++ b/clang/test/CodeGenCXX/debug-info-structured-binding.cpp
@@ -10,7 +10,7 @@
 // CHECK: getelementptr inbounds nuw %struct.A, ptr {{.*}}, i32 0, i32 1, !dbg 
![[Y1_DEBUG_LOC:[0-9]+]]
 // CHECK: getelementptr inbounds nuw %struct.A, ptr {{.*}}, i32 0, i32 1, !dbg 
![[Y2_DEBUG_LOC:[0-9]+]]
 // CHECK: load ptr, ptr %z2, {{.*}}!dbg ![[Z2_DEBUG_LOC:[0-9]+]]
-// CHECK: getelementptr inbounds [2 x i32], ptr {{.*}}, i64 0, i64 1, !dbg 
![[A2_DEBUG_LOC:[0-9]+]]
+// CHECK: getelementptr inbounds [2 x i32], ptr {{.*}}, i{{64|32}} 0, 
i{{64|32}} 1, !dbg ![[A2_DEBUG_LOC:[0-9]+]]
 // CHECK: getelementptr inbounds nuw { i32, i32 }, ptr {{.*}}, i32 0, i32 1, 
!dbg ![[C2_DEBUG_LOC:[0-9]+]]
 // CHECK: extractelement <2 x i32> {{.*}}, i32 1, !dbg ![[V2_DEBUG_LOC:[0-9]+]]
 // CHECK: ![[VAR_0]] = !DILocalVariable(name: "a"

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


[llvm-branch-commits] [llvm] [IR2Vec] Refactor vocabulary to use section-based storage (PR #158376)

2025-10-01 Thread S. VenkataKeerthy via llvm-branch-commits

https://github.com/svkeerthy updated 
https://github.com/llvm/llvm-project/pull/158376

>From 51681f2f98ac43b629d7198f1d0d226f84cc500c Mon Sep 17 00:00:00 2001
From: svkeerthy 
Date: Fri, 12 Sep 2025 22:06:44 +
Subject: [PATCH] VocabStorage

---
 llvm/include/llvm/Analysis/IR2Vec.h   | 218 ---
 llvm/lib/Analysis/IR2Vec.cpp  | 256 +++--
 llvm/lib/Analysis/InlineAdvisor.cpp   |   2 +-
 llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp|   6 +-
 .../FunctionPropertiesAnalysisTest.cpp|  13 +-
 llvm/unittests/Analysis/IR2VecTest.cpp| 347 --
 6 files changed, 648 insertions(+), 194 deletions(-)

diff --git a/llvm/include/llvm/Analysis/IR2Vec.h 
b/llvm/include/llvm/Analysis/IR2Vec.h
index f3f9de460218b..b7c301580a8a4 100644
--- a/llvm/include/llvm/Analysis/IR2Vec.h
+++ b/llvm/include/llvm/Analysis/IR2Vec.h
@@ -45,6 +45,7 @@
 #include "llvm/Support/JSON.h"
 #include 
 #include 
+#include 
 
 namespace llvm {
 
@@ -144,6 +145,73 @@ struct Embedding {
 using InstEmbeddingsMap = DenseMap;
 using BBEmbeddingsMap = DenseMap;
 
+/// Generic storage class for section-based vocabularies.
+/// VocabStorage provides a generic foundation for storing and accessing
+/// embeddings organized into sections.
+class VocabStorage {
+private:
+  /// Section-based storage
+  std::vector> Sections;
+
+  const size_t TotalSize;
+  const unsigned Dimension;
+
+public:
+  /// Default constructor creates empty storage (invalid state)
+  VocabStorage() : Sections(), TotalSize(0), Dimension(0) {}
+
+  /// Create a VocabStorage with pre-organized section data
+  VocabStorage(std::vector> &&SectionData);
+
+  VocabStorage(VocabStorage &&) = default;
+  VocabStorage &operator=(VocabStorage &&) = delete;
+
+  VocabStorage(const VocabStorage &) = delete;
+  VocabStorage &operator=(const VocabStorage &) = delete;
+
+  /// Get total number of entries across all sections
+  size_t size() const { return TotalSize; }
+
+  /// Get number of sections
+  unsigned getNumSections() const {
+return static_cast(Sections.size());
+  }
+
+  /// Section-based access: Storage[sectionId][localIndex]
+  const std::vector &operator[](unsigned SectionId) const {
+assert(SectionId < Sections.size() && "Invalid section ID");
+return Sections[SectionId];
+  }
+
+  /// Get vocabulary dimension
+  unsigned getDimension() const { return Dimension; }
+
+  /// Check if vocabulary is valid (has data)
+  bool isValid() const { return TotalSize > 0; }
+
+  /// Iterator support for section-based access
+  class const_iterator {
+const VocabStorage *Storage;
+unsigned SectionId = 0;
+size_t LocalIndex = 0;
+
+  public:
+const_iterator(const VocabStorage *Storage, unsigned SectionId,
+   size_t LocalIndex)
+: Storage(Storage), SectionId(SectionId), LocalIndex(LocalIndex) {}
+
+LLVM_ABI const Embedding &operator*() const;
+LLVM_ABI const_iterator &operator++();
+LLVM_ABI bool operator==(const const_iterator &Other) const;
+LLVM_ABI bool operator!=(const const_iterator &Other) const;
+  };
+
+  const_iterator begin() const { return const_iterator(this, 0, 0); }
+  const_iterator end() const {
+return const_iterator(this, getNumSections(), 0);
+  }
+};
+
 /// Class for storing and accessing the IR2Vec vocabulary.
 /// The Vocabulary class manages seed embeddings for LLVM IR entities. The
 /// seed embeddings are the initial learned representations of the entities
@@ -164,7 +232,7 @@ using BBEmbeddingsMap = DenseMap;
 class Vocabulary {
   friend class llvm::IR2VecVocabAnalysis;
 
-  // Vocabulary Slot Layout:
+  // Vocabulary Layout:
   // ++--+
   // | Entity Type| Index Range  |
   // ++--+
@@ -180,8 +248,16 @@ class Vocabulary {
   //   and improves learning. Operands include Comparison predicates
   //   (ICmp/FCmp) along with other operand types. This can be extended to
   //   include other specializations in future.
-  using VocabVector = std::vector;
-  VocabVector Vocab;
+  enum class Section : unsigned {
+Opcodes = 0,
+CanonicalTypes = 1,
+Operands = 2,
+Predicates = 3,
+MaxSections
+  };
+
+  // Use section-based storage for better organization and efficiency
+  VocabStorage Storage;
 
   static constexpr unsigned NumICmpPredicates =
   static_cast(CmpInst::LAST_ICMP_PREDICATE) -
@@ -233,10 +309,23 @@ class Vocabulary {
   NumICmpPredicates + NumFCmpPredicates;
 
   Vocabulary() = default;
-  LLVM_ABI Vocabulary(VocabVector &&Vocab) : Vocab(std::move(Vocab)) {}
+  LLVM_ABI Vocabulary(VocabStorage &&Storage) : Storage(std::move(Storage)) {}
+
+  Vocabulary(const Vocabulary &) = delete;
+  Vocabulary &operator=(const Vocabulary &) = delete;
+
+  Vocabulary(Vocabulary &&) = default;
+  Vocabulary &operator=(

[llvm-branch-commits] [llvm] [IR2Vec] Refactor vocabulary to use section-based storage (PR #158376)

2025-10-01 Thread S. VenkataKeerthy via llvm-branch-commits

https://github.com/svkeerthy updated 
https://github.com/llvm/llvm-project/pull/158376

>From 51681f2f98ac43b629d7198f1d0d226f84cc500c Mon Sep 17 00:00:00 2001
From: svkeerthy 
Date: Fri, 12 Sep 2025 22:06:44 +
Subject: [PATCH] VocabStorage

---
 llvm/include/llvm/Analysis/IR2Vec.h   | 218 ---
 llvm/lib/Analysis/IR2Vec.cpp  | 256 +++--
 llvm/lib/Analysis/InlineAdvisor.cpp   |   2 +-
 llvm/tools/llvm-ir2vec/llvm-ir2vec.cpp|   6 +-
 .../FunctionPropertiesAnalysisTest.cpp|  13 +-
 llvm/unittests/Analysis/IR2VecTest.cpp| 347 --
 6 files changed, 648 insertions(+), 194 deletions(-)

diff --git a/llvm/include/llvm/Analysis/IR2Vec.h 
b/llvm/include/llvm/Analysis/IR2Vec.h
index f3f9de460218b..b7c301580a8a4 100644
--- a/llvm/include/llvm/Analysis/IR2Vec.h
+++ b/llvm/include/llvm/Analysis/IR2Vec.h
@@ -45,6 +45,7 @@
 #include "llvm/Support/JSON.h"
 #include 
 #include 
+#include 
 
 namespace llvm {
 
@@ -144,6 +145,73 @@ struct Embedding {
 using InstEmbeddingsMap = DenseMap;
 using BBEmbeddingsMap = DenseMap;
 
+/// Generic storage class for section-based vocabularies.
+/// VocabStorage provides a generic foundation for storing and accessing
+/// embeddings organized into sections.
+class VocabStorage {
+private:
+  /// Section-based storage
+  std::vector> Sections;
+
+  const size_t TotalSize;
+  const unsigned Dimension;
+
+public:
+  /// Default constructor creates empty storage (invalid state)
+  VocabStorage() : Sections(), TotalSize(0), Dimension(0) {}
+
+  /// Create a VocabStorage with pre-organized section data
+  VocabStorage(std::vector> &&SectionData);
+
+  VocabStorage(VocabStorage &&) = default;
+  VocabStorage &operator=(VocabStorage &&) = delete;
+
+  VocabStorage(const VocabStorage &) = delete;
+  VocabStorage &operator=(const VocabStorage &) = delete;
+
+  /// Get total number of entries across all sections
+  size_t size() const { return TotalSize; }
+
+  /// Get number of sections
+  unsigned getNumSections() const {
+return static_cast(Sections.size());
+  }
+
+  /// Section-based access: Storage[sectionId][localIndex]
+  const std::vector &operator[](unsigned SectionId) const {
+assert(SectionId < Sections.size() && "Invalid section ID");
+return Sections[SectionId];
+  }
+
+  /// Get vocabulary dimension
+  unsigned getDimension() const { return Dimension; }
+
+  /// Check if vocabulary is valid (has data)
+  bool isValid() const { return TotalSize > 0; }
+
+  /// Iterator support for section-based access
+  class const_iterator {
+const VocabStorage *Storage;
+unsigned SectionId = 0;
+size_t LocalIndex = 0;
+
+  public:
+const_iterator(const VocabStorage *Storage, unsigned SectionId,
+   size_t LocalIndex)
+: Storage(Storage), SectionId(SectionId), LocalIndex(LocalIndex) {}
+
+LLVM_ABI const Embedding &operator*() const;
+LLVM_ABI const_iterator &operator++();
+LLVM_ABI bool operator==(const const_iterator &Other) const;
+LLVM_ABI bool operator!=(const const_iterator &Other) const;
+  };
+
+  const_iterator begin() const { return const_iterator(this, 0, 0); }
+  const_iterator end() const {
+return const_iterator(this, getNumSections(), 0);
+  }
+};
+
 /// Class for storing and accessing the IR2Vec vocabulary.
 /// The Vocabulary class manages seed embeddings for LLVM IR entities. The
 /// seed embeddings are the initial learned representations of the entities
@@ -164,7 +232,7 @@ using BBEmbeddingsMap = DenseMap;
 class Vocabulary {
   friend class llvm::IR2VecVocabAnalysis;
 
-  // Vocabulary Slot Layout:
+  // Vocabulary Layout:
   // ++--+
   // | Entity Type| Index Range  |
   // ++--+
@@ -180,8 +248,16 @@ class Vocabulary {
   //   and improves learning. Operands include Comparison predicates
   //   (ICmp/FCmp) along with other operand types. This can be extended to
   //   include other specializations in future.
-  using VocabVector = std::vector;
-  VocabVector Vocab;
+  enum class Section : unsigned {
+Opcodes = 0,
+CanonicalTypes = 1,
+Operands = 2,
+Predicates = 3,
+MaxSections
+  };
+
+  // Use section-based storage for better organization and efficiency
+  VocabStorage Storage;
 
   static constexpr unsigned NumICmpPredicates =
   static_cast(CmpInst::LAST_ICMP_PREDICATE) -
@@ -233,10 +309,23 @@ class Vocabulary {
   NumICmpPredicates + NumFCmpPredicates;
 
   Vocabulary() = default;
-  LLVM_ABI Vocabulary(VocabVector &&Vocab) : Vocab(std::move(Vocab)) {}
+  LLVM_ABI Vocabulary(VocabStorage &&Storage) : Storage(std::move(Storage)) {}
+
+  Vocabulary(const Vocabulary &) = delete;
+  Vocabulary &operator=(const Vocabulary &) = delete;
+
+  Vocabulary(Vocabulary &&) = default;
+  Vocabulary &operator=(

[llvm-branch-commits] [llvm] [AMDGPU][SIInsertWaitCnts] Remove redundant TII/TRI/MRI arguments (NFC) (PR #161357)

2025-10-01 Thread Pierre van Houtryve via llvm-branch-commits

Pierre-vh wrote:

### Merge activity

* **Oct 1, 8:51 AM UTC**: A user started a stack merge that includes this pull 
request via 
[Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/161357).


https://github.com/llvm/llvm-project/pull/161357
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] release/21.x: [clang-format] Fix bugs in annotating arrows and square… (PR #161052)

2025-10-01 Thread via llvm-branch-commits

https://github.com/mydeveloperday approved this pull request.


https://github.com/llvm/llvm-project/pull/161052
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [AArch64][SME] Reshuffle emit[prologue|epilogue]() for splitSVEObjects (NFCI) (PR #161217)

2025-10-01 Thread Sander de Smalen via llvm-branch-commits

https://github.com/sdesmalen-arm edited 
https://github.com/llvm/llvm-project/pull/161217
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: make use of C++17 features and LLVM helpers (PR #141665)

2025-10-01 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/141665

>From 3ac1bf12ee9acd480be7125132f4d78e37727c42 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 27 May 2025 21:06:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: make use of C++17 features and LLVM
 helpers

Perform trivial syntactical cleanups:
* make use of structured binding declarations
* use LLVM utility functions when appropriate
* omit braces around single expression inside single-line LLVM_DEBUG()

This patch is NFC aside from minor debug output changes.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 60 +--
 .../AArch64/gs-pauth-debug-output.s   | 14 ++---
 2 files changed, 35 insertions(+), 39 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index fa5db960de335..b032561a43274 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -88,8 +88,8 @@ class TrackedRegisters {
   TrackedRegisters(ArrayRef RegsToTrack)
   : Registers(RegsToTrack),
 RegToIndexMapping(getMappingSize(RegsToTrack), NoIndex) {
-for (unsigned I = 0; I < RegsToTrack.size(); ++I)
-  RegToIndexMapping[RegsToTrack[I]] = I;
+for (auto [MappedIndex, Reg] : llvm::enumerate(RegsToTrack))
+  RegToIndexMapping[Reg] = MappedIndex;
   }
 
   ArrayRef getRegisters() const { return Registers; }
@@ -203,9 +203,9 @@ struct SrcState {
 
 SafeToDerefRegs &= StateIn.SafeToDerefRegs;
 TrustedRegs &= StateIn.TrustedRegs;
-for (unsigned I = 0; I < LastInstWritingReg.size(); ++I)
-  for (const MCInst *J : StateIn.LastInstWritingReg[I])
-LastInstWritingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(LastInstWritingReg, StateIn.LastInstWritingReg))
+  ThisSet.insert_range(OtherSet);
 return *this;
   }
 
@@ -224,11 +224,9 @@ struct SrcState {
 static void printInstsShort(raw_ostream &OS,
 ArrayRef Insts) {
   OS << "Insts: ";
-  for (unsigned I = 0; I < Insts.size(); ++I) {
-auto &Set = Insts[I];
+  for (auto [I, PtrSet] : llvm::enumerate(Insts)) {
 OS << "[" << I << "](";
-for (const MCInst *MCInstP : Set)
-  OS << MCInstP << " ";
+interleave(PtrSet, OS, " ");
 OS << ")";
   }
 }
@@ -416,8 +414,9 @@ class SrcSafetyAnalysis {
 // ... an address can be updated in a safe manner, producing the result
 // which is as trusted as the input address.
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
-  if (Cur.SafeToDerefRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+  auto [DstReg, SrcReg] = *DstAndSrc;
+  if (Cur.SafeToDerefRegs[SrcReg])
+Regs.push_back(DstReg);
 }
 
 // Make sure explicit checker sequence keeps register safe-to-dereference
@@ -469,8 +468,9 @@ class SrcSafetyAnalysis {
 // ... an address can be updated in a safe manner, producing the result
 // which is as trusted as the input address.
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
-  if (Cur.TrustedRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+  auto [DstReg, SrcReg] = *DstAndSrc;
+  if (Cur.TrustedRegs[SrcReg])
+Regs.push_back(DstReg);
 }
 
 return Regs;
@@ -865,9 +865,9 @@ struct DstState {
   return (*this = StateIn);
 
 CannotEscapeUnchecked &= StateIn.CannotEscapeUnchecked;
-for (unsigned I = 0; I < FirstInstLeakingReg.size(); ++I)
-  for (const MCInst *J : StateIn.FirstInstLeakingReg[I])
-FirstInstLeakingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(FirstInstLeakingReg, StateIn.FirstInstLeakingReg))
+  ThisSet.insert_range(OtherSet);
 return *this;
   }
 
@@ -1033,8 +1033,7 @@ class DstSafetyAnalysis {
 
 // ... an address can be updated in a safe manner, or
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Inst)) {
-  MCPhysReg DstReg, SrcReg;
-  std::tie(DstReg, SrcReg) = *DstAndSrc;
+  auto [DstReg, SrcReg] = *DstAndSrc;
   // Note that *all* registers containing the derived values must be safe,
   // both source and destination ones. No temporaries are supported at now.
   if (Cur.CannotEscapeUnchecked[SrcReg] &&
@@ -1074,7 +1073,7 @@ class DstSafetyAnalysis {
 // If this instruction terminates the program immediately, no
 // authentication oracles are possible past this point.
 if (BC.MIB->isTrap(Point)) {
-  LLVM_DEBUG({ traceInst(BC, "Trap instruction found", Point); });
+  LLVM_DEBUG(traceInst(BC, "Trap instruction found", Point));
   DstState Next(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
   Next.CannotEscapeUnchecked.set();
   return Next;
@@ -1249,7 +1248,7 @@ class CFGUnawareDstSafetyAnalysis : public 
DstSafetyAnalysis,
   // starting to analyze Inst.
  

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: make use of C++17 features and LLVM helpers (PR #141665)

2025-10-01 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/141665

>From 3ac1bf12ee9acd480be7125132f4d78e37727c42 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 27 May 2025 21:06:03 +0300
Subject: [PATCH] [BOLT] Gadget scanner: make use of C++17 features and LLVM
 helpers

Perform trivial syntactical cleanups:
* make use of structured binding declarations
* use LLVM utility functions when appropriate
* omit braces around single expression inside single-line LLVM_DEBUG()

This patch is NFC aside from minor debug output changes.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 60 +--
 .../AArch64/gs-pauth-debug-output.s   | 14 ++---
 2 files changed, 35 insertions(+), 39 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index fa5db960de335..b032561a43274 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -88,8 +88,8 @@ class TrackedRegisters {
   TrackedRegisters(ArrayRef RegsToTrack)
   : Registers(RegsToTrack),
 RegToIndexMapping(getMappingSize(RegsToTrack), NoIndex) {
-for (unsigned I = 0; I < RegsToTrack.size(); ++I)
-  RegToIndexMapping[RegsToTrack[I]] = I;
+for (auto [MappedIndex, Reg] : llvm::enumerate(RegsToTrack))
+  RegToIndexMapping[Reg] = MappedIndex;
   }
 
   ArrayRef getRegisters() const { return Registers; }
@@ -203,9 +203,9 @@ struct SrcState {
 
 SafeToDerefRegs &= StateIn.SafeToDerefRegs;
 TrustedRegs &= StateIn.TrustedRegs;
-for (unsigned I = 0; I < LastInstWritingReg.size(); ++I)
-  for (const MCInst *J : StateIn.LastInstWritingReg[I])
-LastInstWritingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(LastInstWritingReg, StateIn.LastInstWritingReg))
+  ThisSet.insert_range(OtherSet);
 return *this;
   }
 
@@ -224,11 +224,9 @@ struct SrcState {
 static void printInstsShort(raw_ostream &OS,
 ArrayRef Insts) {
   OS << "Insts: ";
-  for (unsigned I = 0; I < Insts.size(); ++I) {
-auto &Set = Insts[I];
+  for (auto [I, PtrSet] : llvm::enumerate(Insts)) {
 OS << "[" << I << "](";
-for (const MCInst *MCInstP : Set)
-  OS << MCInstP << " ";
+interleave(PtrSet, OS, " ");
 OS << ")";
   }
 }
@@ -416,8 +414,9 @@ class SrcSafetyAnalysis {
 // ... an address can be updated in a safe manner, producing the result
 // which is as trusted as the input address.
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
-  if (Cur.SafeToDerefRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+  auto [DstReg, SrcReg] = *DstAndSrc;
+  if (Cur.SafeToDerefRegs[SrcReg])
+Regs.push_back(DstReg);
 }
 
 // Make sure explicit checker sequence keeps register safe-to-dereference
@@ -469,8 +468,9 @@ class SrcSafetyAnalysis {
 // ... an address can be updated in a safe manner, producing the result
 // which is as trusted as the input address.
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Point)) {
-  if (Cur.TrustedRegs[DstAndSrc->second])
-Regs.push_back(DstAndSrc->first);
+  auto [DstReg, SrcReg] = *DstAndSrc;
+  if (Cur.TrustedRegs[SrcReg])
+Regs.push_back(DstReg);
 }
 
 return Regs;
@@ -865,9 +865,9 @@ struct DstState {
   return (*this = StateIn);
 
 CannotEscapeUnchecked &= StateIn.CannotEscapeUnchecked;
-for (unsigned I = 0; I < FirstInstLeakingReg.size(); ++I)
-  for (const MCInst *J : StateIn.FirstInstLeakingReg[I])
-FirstInstLeakingReg[I].insert(J);
+for (auto [ThisSet, OtherSet] :
+ llvm::zip_equal(FirstInstLeakingReg, StateIn.FirstInstLeakingReg))
+  ThisSet.insert_range(OtherSet);
 return *this;
   }
 
@@ -1033,8 +1033,7 @@ class DstSafetyAnalysis {
 
 // ... an address can be updated in a safe manner, or
 if (auto DstAndSrc = BC.MIB->analyzeAddressArithmeticsForPtrAuth(Inst)) {
-  MCPhysReg DstReg, SrcReg;
-  std::tie(DstReg, SrcReg) = *DstAndSrc;
+  auto [DstReg, SrcReg] = *DstAndSrc;
   // Note that *all* registers containing the derived values must be safe,
   // both source and destination ones. No temporaries are supported at now.
   if (Cur.CannotEscapeUnchecked[SrcReg] &&
@@ -1074,7 +1073,7 @@ class DstSafetyAnalysis {
 // If this instruction terminates the program immediately, no
 // authentication oracles are possible past this point.
 if (BC.MIB->isTrap(Point)) {
-  LLVM_DEBUG({ traceInst(BC, "Trap instruction found", Point); });
+  LLVM_DEBUG(traceInst(BC, "Trap instruction found", Point));
   DstState Next(NumRegs, RegsToTrackInstsFor.getNumTrackedRegisters());
   Next.CannotEscapeUnchecked.set();
   return Next;
@@ -1249,7 +1248,7 @@ class CFGUnawareDstSafetyAnalysis : public 
DstSafetyAnalysis,
   // starting to analyze Inst.
  

[llvm-branch-commits] [llvm] [BOLT] Gadget scanner: optionally assume auth traps on failure (PR #139778)

2025-10-01 Thread Anatoly Trosinenko via llvm-branch-commits

https://github.com/atrosinenko updated 
https://github.com/llvm/llvm-project/pull/139778

>From 5f07ab9ee7ea514d20d3b9da5f225d68028208b5 Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko 
Date: Tue, 13 May 2025 19:50:41 +0300
Subject: [PATCH 1/2] [BOLT] Gadget scanner: optionally assume auth traps on
 failure

On AArch64 it is possible for an auth instruction to either return an
invalid address value on failure (without FEAT_FPAC) or generate an
error (with FEAT_FPAC). It thus may be possible to never emit explicit
pointer checks, if the target CPU is known to support FEAT_FPAC.

This commit implements an --auth-traps-on-failure command line option,
which essentially makes "safe-to-dereference" and "trusted" register
properties identical and disables scanning for authentication oracles
completely.
---
 bolt/lib/Passes/PAuthGadgetScanner.cpp| 112 +++
 .../binary-analysis/AArch64/cmdline-args.test |   1 +
 .../AArch64/gs-pauth-authentication-oracles.s |   6 +-
 .../binary-analysis/AArch64/gs-pauth-calls.s  |   5 +-
 .../AArch64/gs-pauth-debug-output.s   | 177 ++---
 .../AArch64/gs-pauth-signing-oracles.s|  54 ++---
 .../AArch64/gs-pauth-tail-calls.s | 184 +-
 7 files changed, 314 insertions(+), 225 deletions(-)

diff --git a/bolt/lib/Passes/PAuthGadgetScanner.cpp 
b/bolt/lib/Passes/PAuthGadgetScanner.cpp
index d3e81dbe91138..c6d3981cbb679 100644
--- a/bolt/lib/Passes/PAuthGadgetScanner.cpp
+++ b/bolt/lib/Passes/PAuthGadgetScanner.cpp
@@ -14,6 +14,7 @@
 #include "bolt/Passes/PAuthGadgetScanner.h"
 #include "bolt/Core/ParallelUtilities.h"
 #include "bolt/Passes/DataflowAnalysis.h"
+#include "bolt/Utils/CommandLineOpts.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/MC/MCInst.h"
@@ -26,6 +27,11 @@ namespace llvm {
 namespace bolt {
 namespace PAuthGadgetScanner {
 
+static cl::opt AuthTrapsOnFailure(
+"auth-traps-on-failure",
+cl::desc("Assume authentication instructions always trap on failure"),
+cl::cat(opts::BinaryAnalysisCategory));
+
 [[maybe_unused]] static void traceInst(const BinaryContext &BC, StringRef 
Label,
const MCInst &MI) {
   dbgs() << "  " << Label << ": ";
@@ -364,6 +370,34 @@ class SrcSafetyAnalysis {
 return Clobbered;
   }
 
+  std::optional getRegMadeTrustedByChecking(const MCInst &Inst,
+   SrcState Cur) const {
+// This functions cannot return multiple registers. This is never the case
+// on AArch64.
+std::optional RegCheckedByInst =
+BC.MIB->getAuthCheckedReg(Inst, /*MayOverwrite=*/false);
+if (RegCheckedByInst && Cur.SafeToDerefRegs[*RegCheckedByInst])
+  return *RegCheckedByInst;
+
+auto It = CheckerSequenceInfo.find(&Inst);
+if (It == CheckerSequenceInfo.end())
+  return std::nullopt;
+
+MCPhysReg RegCheckedBySequence = It->second.first;
+const MCInst *FirstCheckerInst = It->second.second;
+
+// FirstCheckerInst should belong to the same basic block (see the
+// assertion in DataflowSrcSafetyAnalysis::run()), meaning it was
+// deterministically processed a few steps before this instruction.
+const SrcState &StateBeforeChecker = getStateBefore(*FirstCheckerInst);
+
+// The sequence checks the register, but it should be authenticated before.
+if (!StateBeforeChecker.SafeToDerefRegs[RegCheckedBySequence])
+  return std::nullopt;
+
+return RegCheckedBySequence;
+  }
+
   // Returns all registers that can be treated as if they are written by an
   // authentication instruction.
   SmallVector getRegsMadeSafeToDeref(const MCInst &Point,
@@ -386,18 +420,38 @@ class SrcSafetyAnalysis {
 Regs.push_back(DstAndSrc->first);
 }
 
+// Make sure explicit checker sequence keeps register safe-to-dereference
+// when the register would be clobbered according to the regular rules:
+//
+//; LR is safe to dereference here
+//mov   x16, x30  ; start of the sequence, LR is s-t-d right before
+//xpaclri ; clobbers LR, LR is not safe anymore
+//cmp   x30, x16
+//b.eq  1f; end of the sequence: LR is marked as trusted
+//brk   0x1234
+//  1:
+//; at this point LR would be marked as trusted,
+//; but not safe-to-dereference
+//
+// or even just
+//
+//; X1 is safe to dereference here
+//ldr x0, [x1, #8]!
+//; X1 is trusted here, but it was clobbered due to address write-back
+if (auto CheckedReg = getRegMadeTrustedByChecking(Point, Cur))
+  Regs.push_back(*CheckedReg);
+
 return Regs;
   }
 
   // Returns all registers made trusted by this instruction.
   SmallVector getRegsMadeTrusted(const MCInst &Point,
 const SrcState &Cur) const {
+assert(!AuthTrapsOnFailure && "Use getRegsMadeSafeToDeref instead");
 SmallVe