From ebc80495ae76333945e58e3d418741ed8f29278f Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Wed, 1 Oct 2025 18:42:39 +0800 Subject: [PATCH 1/2] [InstCombine] Add pre-commit tests. NFC. --- llvm/test/Transforms/InstCombine/funnel.ll | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/llvm/test/Transforms/InstCombine/funnel.ll b/llvm/test/Transforms/InstCombine/funnel.ll index 0e5f0469264c7..daab9d6c28341 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 nsw 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 +} From 498e81f10533ab901aed1c69ef7c48e95798df2e Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Wed, 1 Oct 2025 18:45:00 +0800 Subject: [PATCH 2/2] [InstCombine] Drop poison-generating flags when reusing existing or instruction --- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 7 +++++++ llvm/test/Transforms/InstCombine/funnel.ll | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) 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(U)->dropPoisonGeneratingFlags(); + // Shl + cast(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 daab9d6c28341..e5731080fba44 100644 --- a/llvm/test/Transforms/InstCombine/funnel.ll +++ b/llvm/test/Transforms/InstCombine/funnel.ll @@ -644,7 +644,7 @@ 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 nsw i16 [[ZEXT_X]], 12 +; 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]])