From 579fe671a22c336663b26235f224ea28d1ee0f2b Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Sat, 14 Mar 2026 21:17:31 +0100 Subject: [PATCH 1/2] [InstCombine] Pre commit tests (NFC) --- llvm/test/Transforms/InstCombine/cast_phi.ll | 100 +++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/llvm/test/Transforms/InstCombine/cast_phi.ll b/llvm/test/Transforms/InstCombine/cast_phi.ll index e8db72c8d849e..d82180a222ccc 100644 --- a/llvm/test/Transforms/InstCombine/cast_phi.ll +++ b/llvm/test/Transforms/InstCombine/cast_phi.ll @@ -378,3 +378,103 @@ exit: %ext = zext i8 %iv to i32 ret i32 %ext } + + +declare void @use8(i8) +declare void @use32(i32) + +define i32 @zext_constants_multi_use(i8 %x) { +; CHECK-LABEL: @zext_constants_multi_use( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 42 +; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] +; CHECK: t: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: f: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: [[P:%.*]] = phi i8 [ 5, [[T]] ], [ -1, [[F]] ] +; CHECK-NEXT: call void @use8(i8 [[P]]) +; CHECK-NEXT: [[R:%.*]] = zext i8 [[P]] to i32 +; CHECK-NEXT: ret i32 [[R]] +; +entry: + %cmp = icmp eq i8 %x, 42 + br i1 %cmp, label %t, label %f + +t: + br label %exit + +f: + br label %exit + +exit: + %p = phi i8 [ 5, %t ], [ -1, %f ] + call void @use8(i8 %p) + %r = zext i8 %p to i32 + ret i32 %r +} + +define i32 @sext_constants_multi_use(i8 %x) { +; CHECK-LABEL: @sext_constants_multi_use( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 42 +; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] +; CHECK: t: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: f: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: [[P:%.*]] = phi i8 [ 5, [[T]] ], [ -1, [[F]] ] +; CHECK-NEXT: call void @use8(i8 [[P]]) +; CHECK-NEXT: [[R:%.*]] = sext i8 [[P]] to i32 +; CHECK-NEXT: ret i32 [[R]] +; +entry: + %cmp = icmp eq i8 %x, 42 + br i1 %cmp, label %t, label %f + +t: + br label %exit + +f: + br label %exit + +exit: + %p = phi i8 [ 5, %t ], [ -1, %f ] + call void @use8(i8 %p) + %r = sext i8 %p to i32 + ret i32 %r +} + +define i8 @trunc_constants_multi_use(i8 %x) { +; CHECK-LABEL: @trunc_constants_multi_use( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 42 +; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] +; CHECK: t: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: f: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: [[P:%.*]] = phi i32 [ 5, [[T]] ], [ -1, [[F]] ] +; CHECK-NEXT: call void @use32(i32 [[P]]) +; CHECK-NEXT: [[R:%.*]] = trunc nsw i32 [[P]] to i8 +; CHECK-NEXT: ret i8 [[R]] +; +entry: + %cmp = icmp eq i8 %x, 42 + br i1 %cmp, label %t, label %f + +t: + br label %exit + +f: + br label %exit + +exit: + %p = phi i32 [ 5, %t ], [ -1, %f ] + call void @use32(i32 %p) + %r = trunc i32 %p to i8 + ret i8 %r +} From 2a5845796b77a8bf00a47ba09a5de339c703856e Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Sat, 14 Mar 2026 21:22:15 +0100 Subject: [PATCH 2/2] [InstCombine] Simplify multi use cast of Phi with constant inputs --- llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 8 +++++++- llvm/test/Transforms/InstCombine/cast_phi.ll | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index f2a2e21f6fc95..54ad48decc8f8 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -237,7 +237,13 @@ Instruction *InstCombinerImpl::commonCastTransforms(CastInst &CI) { // legal type. if (!Src->getType()->isIntegerTy() || !CI.getType()->isIntegerTy() || shouldChangeType(CI.getSrcTy(), CI.getType())) - if (Instruction *NV = foldOpIntoPhi(CI, PN)) + if (Instruction *NV = + foldOpIntoPhi(CI, PN, + /*AllowMultipleUses=*/ + is_contained({Instruction::Trunc, Instruction::ZExt, + Instruction::SExt}, + CI.getOpcode()) && + all_of(PN->operands(), IsaPred))) return NV; } diff --git a/llvm/test/Transforms/InstCombine/cast_phi.ll b/llvm/test/Transforms/InstCombine/cast_phi.ll index d82180a222ccc..59929ee420f49 100644 --- a/llvm/test/Transforms/InstCombine/cast_phi.ll +++ b/llvm/test/Transforms/InstCombine/cast_phi.ll @@ -393,9 +393,9 @@ define i32 @zext_constants_multi_use(i8 %x) { ; CHECK: f: ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: +; CHECK-NEXT: [[R:%.*]] = phi i32 [ 5, [[T]] ], [ 255, [[F]] ] ; CHECK-NEXT: [[P:%.*]] = phi i8 [ 5, [[T]] ], [ -1, [[F]] ] ; CHECK-NEXT: call void @use8(i8 [[P]]) -; CHECK-NEXT: [[R:%.*]] = zext i8 [[P]] to i32 ; CHECK-NEXT: ret i32 [[R]] ; entry: @@ -425,9 +425,9 @@ define i32 @sext_constants_multi_use(i8 %x) { ; CHECK: f: ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: +; CHECK-NEXT: [[R:%.*]] = phi i32 [ 5, [[T]] ], [ -1, [[F]] ] ; CHECK-NEXT: [[P:%.*]] = phi i8 [ 5, [[T]] ], [ -1, [[F]] ] ; CHECK-NEXT: call void @use8(i8 [[P]]) -; CHECK-NEXT: [[R:%.*]] = sext i8 [[P]] to i32 ; CHECK-NEXT: ret i32 [[R]] ; entry: @@ -457,9 +457,9 @@ define i8 @trunc_constants_multi_use(i8 %x) { ; CHECK: f: ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: +; CHECK-NEXT: [[R:%.*]] = phi i8 [ 5, [[T]] ], [ -1, [[F]] ] ; CHECK-NEXT: [[P:%.*]] = phi i32 [ 5, [[T]] ], [ -1, [[F]] ] ; CHECK-NEXT: call void @use32(i32 [[P]]) -; CHECK-NEXT: [[R:%.*]] = trunc nsw i32 [[P]] to i8 ; CHECK-NEXT: ret i8 [[R]] ; entry: