[llvm] [InstCombine] Fix invalid fshl -> lshr fold when shift is vector with constant zero lane (PR #210606)
Benji Smith via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 19 08:57:52 PDT 2026
https://github.com/Benjins updated https://github.com/llvm/llvm-project/pull/210606
>From 83d1e834defacda2e53f9db0db73af14cee72cf8 Mon Sep 17 00:00:00 2001
From: Benji Smith <benjsith at gmail.com>
Date: Sun, 19 Jul 2026 11:29:51 -0400
Subject: [PATCH] Fix invalid fshl -> lshr fold
For vectors, this is not valid if a subset of the lanes are constant zero.
Doing this fold introduces poison in those lanes. A similar fix was done for
fshr in 46957a138dea339799059ea5bf032e40042ff185 however the same issue seems
to apply to fshl
Fixes https://github.com/llvm/llvm-project/issues/210605
---
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 4 +++-
llvm/test/Transforms/InstCombine/fsh.ll | 9 +++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 9e3f0e01c002b..9caafb1728cf8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2668,7 +2668,9 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// fshl(0, X, C) --> lshr X, (BW-C)
// fshl(undef, X, C) --> lshr X, (BW-C)
- if (match(Op0, m_ZeroInt()) || match(Op0, m_Undef()))
+ // Similar to fshr -> fshl fold above, this is only valid if C is not zero
+ if ((match(Op0, m_ZeroInt()) || match(Op0, m_Undef())) &&
+ isKnownNonZero(ShAmtC, SQ.getWithInstruction(II)))
return BinaryOperator::CreateLShr(Op1,
ConstantExpr::getSub(WidthC, ShAmtC));
diff --git a/llvm/test/Transforms/InstCombine/fsh.ll b/llvm/test/Transforms/InstCombine/fsh.ll
index 79d3f94182b0b..fd2f8b90b0e0b 100644
--- a/llvm/test/Transforms/InstCombine/fsh.ll
+++ b/llvm/test/Transforms/InstCombine/fsh.ll
@@ -1072,6 +1072,15 @@ define <2 x i32> @fshr_vec_zero_elem(<2 x i32> %x, <2 x i32> %y) {
ret <2 x i32> %fsh
}
+define <2 x i32> @fshl_vec_zero_elem(<2 x i32> %x) {
+; CHECK-LABEL: @fshl_vec_zero_elem(
+; CHECK-NEXT: [[FSH:%.*]] = call <2 x i32> @llvm.fshl.v2i32(<2 x i32> zeroinitializer, <2 x i32> [[X:%.*]], <2 x i32> <i32 2, i32 0>)
+; CHECK-NEXT: ret <2 x i32> [[FSH]]
+;
+ %fsh = call <2 x i32> @llvm.fshl.v2i32(<2 x i32> zeroinitializer, <2 x i32> %x, <2 x i32> <i32 2, i32 0>)
+ ret <2 x i32> %fsh
+}
+
define i16 @fshl_i16_shl(i16 %x, i16 %y) {
; CHECK-LABEL: @fshl_i16_shl(
; CHECK-NEXT: entry:
More information about the llvm-commits
mailing list