[llvm] [InstCombine] Call InstSimplify for cast instructions (PR #162849)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 10 07:15:17 PDT 2025


https://github.com/nikic created https://github.com/llvm/llvm-project/pull/162849

InstCombine currently fails to call into InstSimplify for cast instructions. I noticed this because the transform from https://github.com/llvm/llvm-project/pull/98649 can be triggered via `-passes=instsimplify` but not `-passes=instcombine`, which is not supposed to happen.

>From cd6e6be158f15aa418b484111497a257ece81ad1 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 10 Oct 2025 15:45:08 +0200
Subject: [PATCH 1/2] Add test

---
 llvm/test/Transforms/InstCombine/ptr-int-cast.ll | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/ptr-int-cast.ll b/llvm/test/Transforms/InstCombine/ptr-int-cast.ll
index 69b8f6953d61e..b366cdf52ac15 100644
--- a/llvm/test/Transforms/InstCombine/ptr-int-cast.ll
+++ b/llvm/test/Transforms/InstCombine/ptr-int-cast.ll
@@ -86,3 +86,18 @@ define <4 x ptr> @test7(<4 x i128> %arg) nounwind {
   %p1 = inttoptr <4 x i128> %arg to <4 x ptr>
   ret <4 x ptr> %p1
 }
+
+define i64 @ptrtoint_gep_sub(ptr %ptr, i64 %end.addr) {
+; CHECK-LABEL: @ptrtoint_gep_sub(
+; CHECK-NEXT:    [[PTR_ADDR:%.*]] = ptrtoint ptr [[PTR:%.*]] to i64
+; CHECK-NEXT:    [[SIZE:%.*]] = sub i64 [[END_ADDR1:%.*]], [[PTR_ADDR]]
+; CHECK-NEXT:    [[END:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[SIZE]]
+; CHECK-NEXT:    [[END_ADDR:%.*]] = ptrtoint ptr [[END]] to i64
+; CHECK-NEXT:    ret i64 [[END_ADDR]]
+;
+  %ptr.addr = ptrtoint ptr %ptr to i64
+  %size = sub i64 %end.addr, %ptr.addr
+  %end = getelementptr i8, ptr %ptr, i64 %size
+  %end.addr2 = ptrtoint ptr %end to i64
+  ret i64 %end.addr2
+}

>From 087ad0bea2e991d6c6b546170994cb2d172a6261 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 10 Oct 2025 16:10:16 +0200
Subject: [PATCH 2/2] Call inst simplify for casts

---
 llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp        | 6 +++---
 .../InstCombine/cast-set-preserve-signed-dbg-val.ll         | 4 +---
 llvm/test/Transforms/InstCombine/ptr-int-cast.ll            | 6 +-----
 3 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 4c9b10a094981..cdc559b489e9d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -156,9 +156,9 @@ Instruction *InstCombinerImpl::commonCastTransforms(CastInst &CI) {
   Value *Src = CI.getOperand(0);
   Type *Ty = CI.getType();
 
-  if (auto *SrcC = dyn_cast<Constant>(Src))
-    if (Constant *Res = ConstantFoldCastOperand(CI.getOpcode(), SrcC, Ty, DL))
-      return replaceInstUsesWith(CI, Res);
+  if (Value *Res =
+          simplifyCastInst(CI.getOpcode(), Src, Ty, SQ.getWithInstruction(&CI)))
+    return replaceInstUsesWith(CI, Res);
 
   // Try to eliminate a cast of a cast.
   if (auto *CSrc = dyn_cast<CastInst>(Src)) {   // A->B->C cast
diff --git a/llvm/test/Transforms/InstCombine/cast-set-preserve-signed-dbg-val.ll b/llvm/test/Transforms/InstCombine/cast-set-preserve-signed-dbg-val.ll
index 7cc4446f1038b..ad45d1e3e3e4f 100644
--- a/llvm/test/Transforms/InstCombine/cast-set-preserve-signed-dbg-val.ll
+++ b/llvm/test/Transforms/InstCombine/cast-set-preserve-signed-dbg-val.ll
@@ -11,10 +11,8 @@ define i16 @test5(i16 %A) !dbg !34 {
   call void @llvm.dbg.value(metadata i32 %C, metadata !37, metadata !DIExpression()), !dbg !41
 
   ; Preserve the dbg.value for the DCE'd 32-bit 'and'.
-  ;
-  ; The high 16 bits of the original 'and' require sign-extending the new 16-bit and:
   ; CHECK-NEXT: #dbg_value(i16 [[and]], [[C:![0-9]+]],
-  ; CHECK-SAME:    !DIExpression(DW_OP_LLVM_convert, 16, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value)
+  ; CHECK-SAME:    !DIExpression(DW_OP_LLVM_convert, 16, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned, DW_OP_stack_value)
 
   %D = trunc i32 %C to i16, !dbg !42
   call void @llvm.dbg.value(metadata i16 %D, metadata !38, metadata !DIExpression()), !dbg !42
diff --git a/llvm/test/Transforms/InstCombine/ptr-int-cast.ll b/llvm/test/Transforms/InstCombine/ptr-int-cast.ll
index b366cdf52ac15..82ecbd41e50a7 100644
--- a/llvm/test/Transforms/InstCombine/ptr-int-cast.ll
+++ b/llvm/test/Transforms/InstCombine/ptr-int-cast.ll
@@ -89,11 +89,7 @@ define <4 x ptr> @test7(<4 x i128> %arg) nounwind {
 
 define i64 @ptrtoint_gep_sub(ptr %ptr, i64 %end.addr) {
 ; CHECK-LABEL: @ptrtoint_gep_sub(
-; CHECK-NEXT:    [[PTR_ADDR:%.*]] = ptrtoint ptr [[PTR:%.*]] to i64
-; CHECK-NEXT:    [[SIZE:%.*]] = sub i64 [[END_ADDR1:%.*]], [[PTR_ADDR]]
-; CHECK-NEXT:    [[END:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[SIZE]]
-; CHECK-NEXT:    [[END_ADDR:%.*]] = ptrtoint ptr [[END]] to i64
-; CHECK-NEXT:    ret i64 [[END_ADDR]]
+; CHECK-NEXT:    ret i64 [[END_ADDR:%.*]]
 ;
   %ptr.addr = ptrtoint ptr %ptr to i64
   %size = sub i64 %end.addr, %ptr.addr



More information about the llvm-commits mailing list