[llvm] [X86] Let RegAllocFast lower tied operands (PR #228968)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 4 20:24:26 PDT 2026
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/228968
... so the -O0 pipeline no longer runs TwoAddressInstructionPass.
Follow-ups will enable this for all targets that don't insert passes
with the TwoAddressInstructinPassID anchor.
https://llvm-compile-time-tracker.com/compare.php?from=8ad6c581709df648a2a1e468031a81106a7e00b4&to=33ea7b07c99b9a37f72409029867c50bd1d22a52&stat=instructions:u
-O0 -g, instructions:u geomean: -0.83% (stage1) and -0.85% (stage2).
In a llvm-test-suite build, 2088 of 2563 executables have identical
.text, while 400 have few instructions in total (-0.008%). None gained
extra instructions.
With -O2 -mllvm -regalloc=fast, .text shrinks by 0.12% but the
instruction count grows by 0.09%: RegAllocFast does not convert to
three-address form, so where a tied source stays live,
`leaq 1(%rsi), %rax` becomes `movq %rsi, %rax; incq %rax`.
Test updates:
* O0-pipeline.ll, llc-pipeline-npm.ll: TwoAddressInstructionPass is
gone.
* 2011-06-12-FastAllocSpill.ll: with no two-address copies,
RegAllocFast's "copies coalesced" statistic is no longer printed;
check another statistic.
* switch.ll: the range check now computes in $edi, the argument
register, saving one move.
* atomic-unordered.ll: rmw_fold_srem1 saves one move. In
rmw_fold_sdiv1, the loaded value now goes straight into $rax (imulq's
implicit operand) and is spilled across the imulq, replacing two
register moves.
>From cf44383e514eb615584b6033af29aaeaca96a623 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Mon, 21 Sep 2026 22:43:23 -0700
Subject: [PATCH] [X86] Let RegAllocFast lower tied operands
... so the -O0 pipeline no longer runs TwoAddressInstructionPass.
Follow-ups will enable this for all targets that don't insert passes
with the TwoAddressInstructinPassID anchor.
https://llvm-compile-time-tracker.com/compare.php?from=8ad6c581709df648a2a1e468031a81106a7e00b4&to=33ea7b07c99b9a37f72409029867c50bd1d22a52&stat=instructions:u
-O0 -g, instructions:u geomean: -0.83% (stage1) and -0.85% (stage2).
In a llvm-test-suite build, 2088 of 2563 executables have identical
.text, while 400 have few instructions in total (-0.008%). None gained
extra instructions.
With -O2 -mllvm -regalloc=fast, .text shrinks by 0.12% but the
instruction count grows by 0.09%: RegAllocFast does not convert to
three-address form, so where a tied source stays live,
`leaq 1(%rsi), %rax` becomes `movq %rsi, %rax; incq %rax`.
Test updates:
* O0-pipeline.ll, llc-pipeline-npm.ll: TwoAddressInstructionPass is
gone.
* 2011-06-12-FastAllocSpill.ll: with no two-address copies,
RegAllocFast's "copies coalesced" statistic is no longer printed;
check another statistic.
* switch.ll: the range check now computes in $edi, the argument
register, saving one move.
* atomic-unordered.ll: rmw_fold_srem1 saves one move. In
rmw_fold_sdiv1, the loaded value now goes straight into $rax (imulq's
implicit operand) and is spilled across the imulq, replacing two
register moves.
---
llvm/lib/Target/X86/X86TargetMachine.cpp | 2 ++
.../CodeGen/X86/2011-06-12-FastAllocSpill.ll | 2 +-
llvm/test/CodeGen/X86/O0-pipeline.ll | 9 ------
llvm/test/CodeGen/X86/atomic-unordered.ll | 31 +++++++++----------
llvm/test/CodeGen/X86/llc-pipeline-npm.ll | 2 --
llvm/test/CodeGen/X86/switch.ll | 19 +++++-------
6 files changed, 26 insertions(+), 39 deletions(-)
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 72dab51b67ece..0866df6ab85ec 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -209,6 +209,8 @@ X86TargetMachine::X86TargetMachine(const Target &T, const Triple &TT,
// x86 supports the debug entry values.
setSupportsDebugEntryValues(true);
+ setEnableTiedFastRegAlloc(true);
+
initAsmInfo();
}
diff --git a/llvm/test/CodeGen/X86/2011-06-12-FastAllocSpill.ll b/llvm/test/CodeGen/X86/2011-06-12-FastAllocSpill.ll
index 650cc0a77c7ae..868de7ba9c06a 100644
--- a/llvm/test/CodeGen/X86/2011-06-12-FastAllocSpill.ll
+++ b/llvm/test/CodeGen/X86/2011-06-12-FastAllocSpill.ll
@@ -3,7 +3,7 @@
;
; This test should not cause any spilling with RAFast.
;
-; CHECK: Number of copies coalesced
+; CHECK: Number of machine instrs printed
; CHECK-NOT: Number of stores added
;
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
diff --git a/llvm/test/CodeGen/X86/O0-pipeline.ll b/llvm/test/CodeGen/X86/O0-pipeline.ll
index f722c37dbc198..479b8825ce7b3 100644
--- a/llvm/test/CodeGen/X86/O0-pipeline.ll
+++ b/llvm/test/CodeGen/X86/O0-pipeline.ll
@@ -2,17 +2,9 @@
; pass. Ignore it with 'grep -v'.
; RUN: llc -mtriple=x86_64-- -O0 -debug-pass=Structure < %s -o /dev/null 2>&1 \
; RUN: | grep -v 'Verify generated machine code' | FileCheck %s
-; RUN: llc -mtriple=x86_64-- -O0 -debug-pass=Structure -regalloc-fast-tied < %s -o /dev/null 2>&1 \
-; RUN: | FileCheck %s --check-prefix=TIED
; REQUIRES: asserts
-; The fast register allocator lowers tied operands itself, so
-; TwoAddressInstructionPass drops out while PHIElimination stays.
-; TIED: Eliminate PHI nodes for register allocation
-; TIED-NOT: Two-Address instruction pass
-; TIED: Fast Register Allocator
-
; CHECK-LABEL: Pass Arguments:
; CHECK-NEXT: Target Library Information
; CHECK-NEXT: Runtime Library Function Analysis
@@ -56,7 +48,6 @@
; CHECK-NEXT: X86 DynAlloca Expander
; CHECK-NEXT: Fast Tile Register Preconfigure
; CHECK-NEXT: Eliminate PHI nodes for register allocation
-; CHECK-NEXT: Two-Address instruction pass
; CHECK-NEXT: Fast Register Allocator
; CHECK-NEXT: Fast Tile Register Configure
; CHECK-NEXT: X86 Lower Tile Copy
diff --git a/llvm/test/CodeGen/X86/atomic-unordered.ll b/llvm/test/CodeGen/X86/atomic-unordered.ll
index d309cdf149bc9..480ed35ec4661 100644
--- a/llvm/test/CodeGen/X86/atomic-unordered.ll
+++ b/llvm/test/CodeGen/X86/atomic-unordered.ll
@@ -1422,17 +1422,17 @@ define void @rmw_fold_mul2(ptr %p, i64 %v) {
define void @rmw_fold_sdiv1(ptr %p, i64 %v) {
; CHECK-O0-LABEL: rmw_fold_sdiv1:
; CHECK-O0: # %bb.0:
-; CHECK-O0-NEXT: movq (%rdi), %rcx
-; CHECK-O0-NEXT: movabsq $-8608480567731124087, %rdx # imm = 0x8888888888888889
-; CHECK-O0-NEXT: movq %rcx, %rax
-; CHECK-O0-NEXT: imulq %rdx
+; CHECK-O0-NEXT: movq (%rdi), %rax
+; CHECK-O0-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
+; CHECK-O0-NEXT: movabsq $-8608480567731124087, %rcx # imm = 0x8888888888888889
+; CHECK-O0-NEXT: imulq %rcx
+; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
+; CHECK-O0-NEXT: addq %rax, %rdx
; CHECK-O0-NEXT: movq %rdx, %rax
-; CHECK-O0-NEXT: addq %rcx, %rax
-; CHECK-O0-NEXT: movq %rax, %rcx
-; CHECK-O0-NEXT: shrq $63, %rcx
-; CHECK-O0-NEXT: sarq $3, %rax
-; CHECK-O0-NEXT: addq %rcx, %rax
-; CHECK-O0-NEXT: movq %rax, (%rdi)
+; CHECK-O0-NEXT: shrq $63, %rax
+; CHECK-O0-NEXT: sarq $3, %rdx
+; CHECK-O0-NEXT: addq %rax, %rdx
+; CHECK-O0-NEXT: movq %rdx, (%rdi)
; CHECK-O0-NEXT: retq
;
; CHECK-O3-LABEL: rmw_fold_sdiv1:
@@ -1550,13 +1550,12 @@ define void @rmw_fold_srem1(ptr %p, i64 %v) {
; CHECK-O0-NEXT: movabsq $-8608480567731124087, %rcx # imm = 0x8888888888888889
; CHECK-O0-NEXT: imulq %rcx
; CHECK-O0-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
+; CHECK-O0-NEXT: addq %rax, %rdx
; CHECK-O0-NEXT: movq %rdx, %rcx
-; CHECK-O0-NEXT: addq %rax, %rcx
-; CHECK-O0-NEXT: movq %rcx, %rdx
-; CHECK-O0-NEXT: shrq $63, %rdx
-; CHECK-O0-NEXT: sarq $3, %rcx
-; CHECK-O0-NEXT: addq %rdx, %rcx
-; CHECK-O0-NEXT: leaq (%rcx,%rcx,4), %rcx
+; CHECK-O0-NEXT: shrq $63, %rcx
+; CHECK-O0-NEXT: sarq $3, %rdx
+; CHECK-O0-NEXT: addq %rcx, %rdx
+; CHECK-O0-NEXT: leaq (%rdx,%rdx,4), %rcx
; CHECK-O0-NEXT: leaq (%rcx,%rcx,2), %rcx
; CHECK-O0-NEXT: subq %rcx, %rax
; CHECK-O0-NEXT: movq %rax, (%rdi)
diff --git a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
index d02b6e9ff4c9f..bc131357f6419 100644
--- a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
+++ b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
@@ -49,7 +49,6 @@
; O0-NEXT: x86-dyn-alloca-expander
; O0-NEXT: x86-fast-pre-tile-config
; O0-NEXT: phi-node-elimination
-; O0-NEXT: two-address-instruction
; O0-NEXT: regallocfast
; O0-NEXT: x86-lower-tile-copy
; O0-NEXT: x86-fp-stackifier
@@ -252,7 +251,6 @@
; O0-WINDOWS-NEXT: x86-dyn-alloca-expander
; O0-WINDOWS-NEXT: x86-fast-pre-tile-config
; O0-WINDOWS-NEXT: phi-node-elimination
-; O0-WINDOWS-NEXT: two-address-instruction
; O0-WINDOWS-NEXT: regallocfast
; O0-WINDOWS-NEXT: x86-lower-tile-copy
; O0-WINDOWS-NEXT: x86-fp-stackifier
diff --git a/llvm/test/CodeGen/X86/switch.ll b/llvm/test/CodeGen/X86/switch.ll
index c75819c2fd2c5..2489e9123d46d 100644
--- a/llvm/test/CodeGen/X86/switch.ll
+++ b/llvm/test/CodeGen/X86/switch.ll
@@ -27,11 +27,10 @@ define void @basic(i32 %x) {
; NOOPT: # %bb.0: # %entry
; NOOPT-NEXT: pushq %rax
; NOOPT-NEXT: .cfi_def_cfa_offset 16
+; NOOPT-NEXT: decl %edi
; NOOPT-NEXT: movl %edi, %eax
-; NOOPT-NEXT: decl %eax
-; NOOPT-NEXT: movl %eax, %ecx
-; NOOPT-NEXT: movq %rcx, (%rsp) # 8-byte Spill
-; NOOPT-NEXT: subl $4, %eax
+; NOOPT-NEXT: movq %rax, (%rsp) # 8-byte Spill
+; NOOPT-NEXT: subl $4, %edi
; NOOPT-NEXT: ja .LBB0_4
; NOOPT-NEXT: # %bb.5: # %entry
; NOOPT-NEXT: movq (%rsp), %rax # 8-byte Reload
@@ -166,11 +165,10 @@ define void @basic_nojumptable_false(i32 %x) "no-jump-tables"="false" {
; NOOPT: # %bb.0: # %entry
; NOOPT-NEXT: pushq %rax
; NOOPT-NEXT: .cfi_def_cfa_offset 16
+; NOOPT-NEXT: decl %edi
; NOOPT-NEXT: movl %edi, %eax
-; NOOPT-NEXT: decl %eax
-; NOOPT-NEXT: movl %eax, %ecx
-; NOOPT-NEXT: movq %rcx, (%rsp) # 8-byte Spill
-; NOOPT-NEXT: subl $4, %eax
+; NOOPT-NEXT: movq %rax, (%rsp) # 8-byte Spill
+; NOOPT-NEXT: subl $4, %edi
; NOOPT-NEXT: ja .LBB2_4
; NOOPT-NEXT: # %bb.5: # %entry
; NOOPT-NEXT: movq (%rsp), %rax # 8-byte Reload
@@ -2602,9 +2600,8 @@ define void @range_with_unreachable_fallthrough(i32 %i) {
; NOOPT: # %bb.0: # %entry
; NOOPT-NEXT: pushq %rax
; NOOPT-NEXT: .cfi_def_cfa_offset 16
-; NOOPT-NEXT: movl %edi, %eax
-; NOOPT-NEXT: decl %eax
-; NOOPT-NEXT: subl $3, %eax
+; NOOPT-NEXT: decl %edi
+; NOOPT-NEXT: subl $3, %edi
; NOOPT-NEXT: jb .LBB25_1
; NOOPT-NEXT: jmp .LBB25_5
; NOOPT-NEXT: .LBB25_5: # %entry
More information about the llvm-commits
mailing list