[llvm] [AArch64] Enable dead register definitions at O0 (PR #145174)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 21 08:58:46 PDT 2025


https://github.com/AZero13 created https://github.com/llvm/llvm-project/pull/145174

This is because the assembler/disassembler will otherwise show this as an adds or subs and not cmp or cmn. Even gcc does this. And, this is just allocating register to 0 reg. Will this optimize -O0? Well, minimally it will put less register pressure maybe, but that is not the point. The point is that it should resolve to aliases for better understanding, which is why -O0 exists to begin with.

>From 80e63f42c99832aa85f7a0289376203330bbf2d3 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sat, 21 Jun 2025 11:45:34 -0400
Subject: [PATCH 1/2] Pre-commit test

---
 llvm/test/CodeGen/AArch64/fast-isel-O0-cmp | 38 ++++++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 llvm/test/CodeGen/AArch64/fast-isel-O0-cmp

diff --git a/llvm/test/CodeGen/AArch64/fast-isel-O0-cmp b/llvm/test/CodeGen/AArch64/fast-isel-O0-cmp
new file mode 100644
index 0000000000000..88033a831511f
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/fast-isel-O0-cmp
@@ -0,0 +1,38 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=aarch64-linux-gnu -O0 -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK
+
+; even in -O0, cmp should be cmp
+define i1 @cmp(i32 %0) {
+; CHECK-LABEL: cmp:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    subs w8, w0, #5
+; CHECK-NEXT:    cset w0, gt
+; CHECK-NEXT:    // kill: def $w1 killed $w0
+; CHECK-NEXT:    ret
+  %2 = icmp sgt i32 %0, 5
+  ret i1 %2
+}
+
+define i1 @cmn(i32 %0) {
+; CHECK-LABEL: cmn:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adds w8, w0, #5
+; CHECK-NEXT:    cset w0, gt
+; CHECK-NEXT:    // kill: def $w1 killed $w0
+; CHECK-NEXT:    ret
+  %2 = icmp sgt i32 %0, -5
+  ret i1 %2
+}
+
+; Test that 0 is cmp
+define i1 @cmp0(i32 %0) {
+; CHECK-LABEL: cmp0:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    subs w8, w0, #0
+; CHECK-NEXT:    cset w0, gt
+; CHECK-NEXT:    // kill: def $w1 killed $w0
+; CHECK-NEXT:    ret
+  %2 = icmp sgt i32 %0, 0
+  ret i1 %2
+}
+

>From be6d1fdd65f380796bb586a3f1e0d250757645dc Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sat, 21 Jun 2025 11:55:10 -0400
Subject: [PATCH 2/2] Enable dead register definitions at O0

This is because the assembler/disassembler will otherwise show this as an adds or subs and not cmp or cmn. Even gcc does this. And, this is just allocating register to 0 reg. Will this optimize -O0? Well, minimally it will put less register pressure maybe, but that is not the point. The point is that it should resolve to aliases for better understanding, which is why -O0 exists to begin with.
---
 llvm/lib/Target/AArch64/AArch64TargetMachine.cpp | 4 ++--
 llvm/test/CodeGen/AArch64/fast-isel-O0-cmp       | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index 8150e91c8ba52..cec2c1b8374c6 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -803,8 +803,8 @@ bool AArch64PassConfig::addILPOpts() {
 
 void AArch64PassConfig::addPreRegAlloc() {
   // Change dead register definitions to refer to the zero register.
-  if (TM->getOptLevel() != CodeGenOptLevel::None &&
-      EnableDeadRegisterElimination)
+  // This is beneficial even at -O0 as we can show CMP/CMN in the assembler output.
+  if (EnableDeadRegisterElimination)
     addPass(createAArch64DeadRegisterDefinitions());
 
   // Use AdvSIMD scalar instructions whenever profitable.
diff --git a/llvm/test/CodeGen/AArch64/fast-isel-O0-cmp b/llvm/test/CodeGen/AArch64/fast-isel-O0-cmp
index 88033a831511f..e5d97df40db25 100644
--- a/llvm/test/CodeGen/AArch64/fast-isel-O0-cmp
+++ b/llvm/test/CodeGen/AArch64/fast-isel-O0-cmp
@@ -5,7 +5,7 @@
 define i1 @cmp(i32 %0) {
 ; CHECK-LABEL: cmp:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    subs w8, w0, #5
+; CHECK-NEXT:    cmp w0, #5
 ; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    // kill: def $w1 killed $w0
 ; CHECK-NEXT:    ret
@@ -16,7 +16,7 @@ define i1 @cmp(i32 %0) {
 define i1 @cmn(i32 %0) {
 ; CHECK-LABEL: cmn:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    adds w8, w0, #5
+; CHECK-NEXT:    cmn w0, #5
 ; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    // kill: def $w1 killed $w0
 ; CHECK-NEXT:    ret
@@ -28,7 +28,7 @@ define i1 @cmn(i32 %0) {
 define i1 @cmp0(i32 %0) {
 ; CHECK-LABEL: cmp0:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    subs w8, w0, #0
+; CHECK-NEXT:    cmp w0, #0
 ; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    // kill: def $w1 killed $w0
 ; CHECK-NEXT:    ret



More information about the llvm-commits mailing list