From 6cacbbe0b7d572bc9c111ec2f45eec58bacf63e2 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 14 May 2021 13:41:14 -0400 Subject: [PATCH] [InstCombine] drop poison flags when simplifying 'shl' based on demanded bits As with other transforms in demanded bits, we must be careful not to wrongly propagate nsw/nuw if we are reducing values leading up to the shift. This bug was introduced with 1b24f35f843c and leads to the miscompile shown in: https://llvm.org/PR50341 --- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 5 ++++- test/Transforms/InstCombine/shl-demand.ll | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 2b9c1f2ad3d..89575989255 100644 --- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -575,8 +575,11 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, // demanding those bits from the pre-shifted operand either. if (unsigned CTLZ = DemandedMask.countLeadingZeros()) { APInt DemandedFromOp(APInt::getLowBitsSet(BitWidth, BitWidth - CTLZ)); - if (SimplifyDemandedBits(I, 0, DemandedFromOp, Known, Depth + 1)) + if (SimplifyDemandedBits(I, 0, DemandedFromOp, Known, Depth + 1)) { + // We can't guarantee that nsw/nuw hold after simplifying the operand. + I->dropPoisonGeneratingFlags(); return I; + } } computeKnownBits(I, Known, Depth, CxtI); } diff --git a/test/Transforms/InstCombine/shl-demand.ll b/test/Transforms/InstCombine/shl-demand.ll index 245c7033190..11c2de8e58d 100644 --- a/test/Transforms/InstCombine/shl-demand.ll +++ b/test/Transforms/InstCombine/shl-demand.ll @@ -89,7 +89,7 @@ define i32 @set_shl_mask(i32 %x, i32 %y) { define i8 @must_drop_poison(i32 %x, i32 %y) { ; CHECK-LABEL: @must_drop_poison( -; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[S:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: [[T:%.*]] = trunc i32 [[S]] to i8 ; CHECK-NEXT: ret i8 [[T]] ;