[llvm] c090548 - [InstCombine] Drop poison-generating flags when reusing existing or instruction (#161504)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 1 07:02:12 PDT 2025
Author: Yingwei Zheng
Date: 2025-10-01T22:02:08+08:00
New Revision: c09054866a1ad6c250e6c972d369b9023abb4b3b
URL: https://github.com/llvm/llvm-project/commit/c09054866a1ad6c250e6c972d369b9023abb4b3b
DIFF: https://github.com/llvm/llvm-project/commit/c09054866a1ad6c250e6c972d369b9023abb4b3b.diff
LOG: [InstCombine] Drop poison-generating flags when reusing existing or instruction (#161504)
Closes https://github.com/llvm/llvm-project/issues/161493.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/funnel.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 4b7793f6e010b..9b272c4721cbd 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3080,6 +3080,13 @@ InstCombinerImpl::convertOrOfShiftsToFunnelShift(Instruction &Or) {
assert(ZextLowShlAmt->uge(HighSize) &&
ZextLowShlAmt->ule(Width - LowSize) && "Invalid concat");
+ // We cannot reuse the result if it may produce poison.
+ // Drop poison generating flags in the expression tree.
+ // Or
+ cast<Instruction>(U)->dropPoisonGeneratingFlags();
+ // Shl
+ cast<Instruction>(X)->dropPoisonGeneratingFlags();
+
FShiftArgs = {U, U, ConstantInt::get(Or0->getType(), *ZextHighShlAmt)};
break;
}
diff --git a/llvm/test/Transforms/InstCombine/funnel.ll b/llvm/test/Transforms/InstCombine/funnel.ll
index 0e5f0469264c7..e5731080fba44 100644
--- a/llvm/test/Transforms/InstCombine/funnel.ll
+++ b/llvm/test/Transforms/InstCombine/funnel.ll
@@ -635,3 +635,29 @@ define i32 @test_rotl_and_neg_wrong_mask(i32 %x, i32 %shamt) {
%or = or i32 %shl, %shr
ret i32 %or
}
+
+declare void @use(i16)
+
+; Make sure the reused result does not produce poison.
+
+define i16 @fshl_concat_vector_may_produce_poison(i4 %x, i12 %y) {
+; CHECK-LABEL: @fshl_concat_vector_may_produce_poison(
+; CHECK-NEXT: [[X_FR:%.*]] = freeze i4 [[X:%.*]]
+; CHECK-NEXT: [[ZEXT_X:%.*]] = zext i4 [[X_FR]] to i16
+; CHECK-NEXT: [[SLX:%.*]] = shl nuw i16 [[ZEXT_X]], 12
+; CHECK-NEXT: [[ZEXT_Y:%.*]] = zext i12 [[Y:%.*]] to i16
+; CHECK-NEXT: [[XY:%.*]] = or disjoint i16 [[SLX]], [[ZEXT_Y]]
+; CHECK-NEXT: call void @use(i16 [[XY]])
+; CHECK-NEXT: [[YX:%.*]] = call i16 @llvm.fshl.i16(i16 [[XY]], i16 [[XY]], i16 4)
+; CHECK-NEXT: ret i16 [[YX]]
+;
+ %x.fr = freeze i4 %x
+ %zext.x = zext i4 %x.fr to i16
+ %slx = shl nuw nsw i16 %zext.x, 12
+ %zext.y = zext i12 %y to i16
+ %xy = or disjoint i16 %slx, %zext.y
+ call void @use(i16 %xy)
+ %sly = shl nuw i16 %zext.y, 4
+ %yx = or disjoint i16 %sly, %zext.x
+ ret i16 %yx
+}
More information about the llvm-commits
mailing list