[llvm] [InstCombine] Return early for zext(bitcast half to i16) (PR #201815)

Igor Wodiany via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 5 04:45:50 PDT 2026


https://github.com/IgWod created https://github.com/llvm/llvm-project/pull/201815

This provides a measurable improvement (up to 4-5%) to compile-time for selected AMDGPU workloads. Without this change `visitZext` will iterate through the half ops to determine the fp class so that it can flag whether the sign bit is zero or one in isKnownNonNegative.

>From 852af0ff6563c2e9b61a077d5a81b645318ac595 Mon Sep 17 00:00:00 2001
From: Igor Wodiany <igor.wodiany at amd.com>
Date: Fri, 5 Jun 2026 10:49:03 +0100
Subject: [PATCH] [InstCombine] Return early for zext(bitcast half to i16)

This provides a measurable improvement (up to 4-5%) to compile-time
for selected AMDGPU workloads. Without this change `visitZext` will
iterate through the half ops to determine the fp class so that it
can flag whether the sign bit is zero or one in isKnownNonNegative.

Co-authored-by: Antonio Carpio <antonio.carpio at amd.com>
---
 .../InstCombine/InstCombineCasts.cpp          |  7 ++++++
 llvm/test/Transforms/InstCombine/zext.ll      | 22 +++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index d371218e61108..5bcfd0d4dfce7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1572,6 +1572,13 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &Zext) {
   if (SrcTy->isIntOrIntVectorTy(1) && Zext.hasNonNeg())
     return replaceInstUsesWith(Zext, Constant::getNullValue(Zext.getType()));
 
+  // zext(bitcast half to i16) matches no folds below; bail out early.
+  Value *BitcastSrc;
+  if (SrcTy->isIntOrIntVectorTy(16) &&
+      match(Src, m_BitCast(m_Value(BitcastSrc))) &&
+      BitcastSrc->getType()->getScalarType()->isHalfTy())
+    return nullptr;
+
   // Try to extend the entire expression tree to the wide destination type.
   unsigned BitsToClear;
   if (shouldChangeType(SrcTy, DestTy) &&
diff --git a/llvm/test/Transforms/InstCombine/zext.ll b/llvm/test/Transforms/InstCombine/zext.ll
index e4d18e9395219..513012ff73959 100644
--- a/llvm/test/Transforms/InstCombine/zext.ll
+++ b/llvm/test/Transforms/InstCombine/zext.ll
@@ -976,3 +976,25 @@ entry:
   %res = zext nneg i2 %x to i32
   ret i32 %res
 }
+
+define i32 @zext_bitcast_half_to_i16(half %x) {
+; CHECK-LABEL: @zext_bitcast_half_to_i16(
+; CHECK-NEXT:    [[BC:%.*]] = bitcast half [[X:%.*]] to i16
+; CHECK-NEXT:    [[Z:%.*]] = zext i16 [[BC]] to i32
+; CHECK-NEXT:    ret i32 [[Z]]
+;
+  %bc = bitcast half %x to i16
+  %z = zext i16 %bc to i32
+  ret i32 %z
+}
+
+define <4 x i32> @zext_bitcast_v4half_to_v4i16(<4 x half> %x) {
+; CHECK-LABEL: @zext_bitcast_v4half_to_v4i16(
+; CHECK-NEXT:    [[BC:%.*]] = bitcast <4 x half> [[X:%.*]] to <4 x i16>
+; CHECK-NEXT:    [[Z:%.*]] = zext <4 x i16> [[BC]] to <4 x i32>
+; CHECK-NEXT:    ret <4 x i32> [[Z]]
+;
+  %bc = bitcast <4 x half> %x to <4 x i16>
+  %z = zext <4 x i16> %bc to <4 x i32>
+  ret <4 x i32> %z
+}
\ No newline at end of file



More information about the llvm-commits mailing list