[llvm] Do not emit right shift by 0 in DWARF expressions (PR #162738)

Tom Tromey via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 9 14:20:18 PDT 2025


https://github.com/tromey created https://github.com/llvm/llvm-project/pull/162738

DW_OP_LLVM_extract_bits_zext and DW_OP_LLVM_extract_bits_sext can end up emitting "DW_OP_constu 0; DW_OP_shr" when given certain arguments. However, a shift by zero is not useful, and so it can be omitted.

>From eb3f34766b6596fdbdc06ab0d5f6fdc36785a419 Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey at adacore.com>
Date: Thu, 9 Oct 2025 14:04:48 -0600
Subject: [PATCH] Do not emit right shift by 0 in DWARF expressions

DW_OP_LLVM_extract_bits_zext and DW_OP_LLVM_extract_bits_sext can end
up emitting "DW_OP_constu 0; DW_OP_shr" when given certain arguments.
However, a shift by zero is not useful, and so it can be omitted.
---
 llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp    | 10 ++++++----
 llvm/test/DebugInfo/X86/DW_OP_LLVM_extract_bits.ll |  5 +++++
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index bc0bb349be249..f0f086184656a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -587,10 +587,12 @@ bool DwarfExpression::addExpression(
         emitUnsigned(LeftShift);
         emitOp(dwarf::DW_OP_shl);
       }
-      emitOp(dwarf::DW_OP_constu);
-      emitUnsigned(RightShift);
-      emitOp(OpNum == dwarf::DW_OP_LLVM_extract_bits_sext ? dwarf::DW_OP_shra
-                                                          : dwarf::DW_OP_shr);
+      if (RightShift) {
+        emitOp(dwarf::DW_OP_constu);
+        emitUnsigned(RightShift);
+        emitOp(OpNum == dwarf::DW_OP_LLVM_extract_bits_sext ? dwarf::DW_OP_shra
+                                                            : dwarf::DW_OP_shr);
+      }
 
       // The value is now at the top of the stack, so set the location to
       // implicit so that we get a stack_value at the end.
diff --git a/llvm/test/DebugInfo/X86/DW_OP_LLVM_extract_bits.ll b/llvm/test/DebugInfo/X86/DW_OP_LLVM_extract_bits.ll
index 8342d42f6a292..5928127866f7e 100644
--- a/llvm/test/DebugInfo/X86/DW_OP_LLVM_extract_bits.ll
+++ b/llvm/test/DebugInfo/X86/DW_OP_LLVM_extract_bits.ll
@@ -67,6 +67,8 @@ entry:
 ; CHECK: DW_TAG_variable
 ; CHECK: DW_AT_location (DW_OP_fbreg -4, DW_OP_plus_uconst 0x3, DW_OP_deref_size 0x1, DW_OP_constu 0x38, DW_OP_shl, DW_OP_constu 0x39, DW_OP_shr, DW_OP_stack_value)
 ; CHECK: DW_AT_name ("z")
+; CHECK: DW_AT_location (DW_OP_fbreg -4, DW_OP_deref_size 0x8, DW_OP_stack_value)
+; CHECK: DW_AT_name ("q")
 
 define i32 @test4() !dbg !28 {
 entry:
@@ -74,6 +76,7 @@ entry:
   tail call void @llvm.dbg.declare(metadata ptr %0, metadata !29, metadata !DIExpression(DW_OP_LLVM_extract_bits_zext, 31, 1)), !dbg !30
   tail call void @llvm.dbg.declare(metadata ptr %0, metadata !31, metadata !DIExpression(DW_OP_LLVM_extract_bits_sext, 1, 31)), !dbg !30
   tail call void @llvm.dbg.declare(metadata ptr %0, metadata !32, metadata !DIExpression(DW_OP_plus_uconst, 3, DW_OP_LLVM_extract_bits_zext, 1, 7)), !dbg !30
+  tail call void @llvm.dbg.declare(metadata ptr %0, metadata !33, metadata !DIExpression(DW_OP_LLVM_extract_bits_zext, 0, 64)), !dbg !30
   ret i32 0, !dbg !30
 }
 
@@ -116,3 +119,5 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
 !30 = !DILocation(line: 0, scope: !28)
 !31 = !DILocalVariable(name: "y", scope: !28, file: !3, type: !19)
 !32 = !DILocalVariable(name: "z", scope: !28, file: !3, type: !9)
+!33 = !DILocalVariable(name: "q", scope: !28, file: !3, type: !34)
+!34 = !DIBasicType(name: "uint64_t", size: 64, encoding: DW_ATE_unsigned)



More information about the llvm-commits mailing list