[InstCombine] fix one-use condition for shift transform

This transform is written in a confusing style,
and I suspect it is at fault for a more serious
bug noted in PR51567.

But it's been around forever, so I'm making the
minimal change to fix another bug - it could
increase instructions because it was not checking
uses.
This commit is contained in:
Sanjay Patel 2021-09-06 10:22:24 -04:00
parent 982a15cb3f
commit fbb78668f2
2 changed files with 4 additions and 5 deletions

View File

@ -690,6 +690,9 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
if (Instruction *FoldedShift = foldBinOpIntoSelectOrPhi(I))
return FoldedShift;
if (!Op0->hasOneUse())
return nullptr;
// Fold shift2(trunc(shift1(x,c1)), c2) -> trunc(shift2(shift1(x,c1),c2))
if (auto *TI = dyn_cast<TruncInst>(Op0)) {
// If 'shift2' is an ashr, we would have to get the sign bit into a funny
@ -728,9 +731,6 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
}
}
if (!Op0->hasOneUse())
return nullptr;
if (auto *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
// Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
Value *V1;

View File

@ -217,8 +217,7 @@ define i16 @shl_tr_shl_constant_shift_amount_uses(i32 %x) {
; CHECK-NEXT: call void @use32(i32 [[SHL]])
; CHECK-NEXT: [[TR:%.*]] = trunc i32 [[SHL]] to i16
; CHECK-NEXT: call void @use16(i16 [[TR]])
; CHECK-NEXT: [[X_TR:%.*]] = trunc i32 [[X]] to i16
; CHECK-NEXT: [[R:%.*]] = shl i16 [[X_TR]], 7
; CHECK-NEXT: [[R:%.*]] = shl i16 [[TR]], 4
; CHECK-NEXT: ret i16 [[R]]
;
%shl = shl i32 %x, 3