Skip to content

Commit f2898de

Browse files
authored
[InstCombine] Don't mix X << Y / Z << Y with X << Y / X << Z (llvm#69302)
Fixes llvm#69291. This patch improve the logic handling different patterns to avoid mixing these pattern.
1 parent c4ba84d commit f2898de

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -923,8 +923,7 @@ static bool isMultiple(const APInt &C1, const APInt &C2, APInt &Quotient,
923923
return Remainder.isMinValue();
924924
}
925925

926-
static Instruction *foldIDivShl(BinaryOperator &I,
927-
InstCombiner::BuilderTy &Builder) {
926+
static Value *foldIDivShl(BinaryOperator &I, InstCombiner::BuilderTy &Builder) {
928927
assert((I.getOpcode() == Instruction::SDiv ||
929928
I.getOpcode() == Instruction::UDiv) &&
930929
"Expected integer divide");
@@ -933,7 +932,6 @@ static Instruction *foldIDivShl(BinaryOperator &I,
933932
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
934933
Type *Ty = I.getType();
935934

936-
Instruction *Ret = nullptr;
937935
Value *X, *Y, *Z;
938936

939937
// With appropriate no-wrap constraints, remove a common factor in the
@@ -948,12 +946,12 @@ static Instruction *foldIDivShl(BinaryOperator &I,
948946

949947
// (X * Y) u/ (X << Z) --> Y u>> Z
950948
if (!IsSigned && HasNUW)
951-
Ret = BinaryOperator::CreateLShr(Y, Z);
949+
return Builder.CreateLShr(Y, Z, "", I.isExact());
952950

953951
// (X * Y) s/ (X << Z) --> Y s/ (1 << Z)
954952
if (IsSigned && HasNSW && (Op0->hasOneUse() || Op1->hasOneUse())) {
955953
Value *Shl = Builder.CreateShl(ConstantInt::get(Ty, 1), Z);
956-
Ret = BinaryOperator::CreateSDiv(Y, Shl);
954+
return Builder.CreateSDiv(Y, Shl, "", I.isExact());
957955
}
958956
}
959957

@@ -971,13 +969,13 @@ static Instruction *foldIDivShl(BinaryOperator &I,
971969
((Shl0->hasNoUnsignedWrap() && Shl1->hasNoUnsignedWrap()) ||
972970
(Shl0->hasNoUnsignedWrap() && Shl0->hasNoSignedWrap() &&
973971
Shl1->hasNoSignedWrap())))
974-
Ret = BinaryOperator::CreateUDiv(X, Y);
972+
return Builder.CreateUDiv(X, Y, "", I.isExact());
975973

976974
// For signed div, we need 'nsw' on both shifts + 'nuw' on the divisor.
977975
// (X << Z) / (Y << Z) --> X / Y
978976
if (IsSigned && Shl0->hasNoSignedWrap() && Shl1->hasNoSignedWrap() &&
979977
Shl1->hasNoUnsignedWrap())
980-
Ret = BinaryOperator::CreateSDiv(X, Y);
978+
return Builder.CreateSDiv(X, Y, "", I.isExact());
981979
}
982980

983981
// If X << Y and X << Z does not overflow, then:
@@ -998,15 +996,11 @@ static Instruction *foldIDivShl(BinaryOperator &I,
998996
/*HasNSW*/
999997
IsSigned ? (Shl0->hasNoUnsignedWrap() || Shl1->hasNoUnsignedWrap())
1000998
: Shl0->hasNoSignedWrap());
1001-
Ret = BinaryOperator::CreateLShr(Dividend, Z);
999+
return Builder.CreateLShr(Dividend, Z, "", I.isExact());
10021000
}
10031001
}
10041002

1005-
if (!Ret)
1006-
return nullptr;
1007-
1008-
Ret->setIsExact(I.isExact());
1009-
return Ret;
1003+
return nullptr;
10101004
}
10111005

10121006
/// This function implements the transforms common to both integer division
@@ -1183,8 +1177,8 @@ Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
11831177
return NewDiv;
11841178
}
11851179

1186-
if (Instruction *R = foldIDivShl(I, Builder))
1187-
return R;
1180+
if (Value *R = foldIDivShl(I, Builder))
1181+
return replaceInstUsesWith(I, R);
11881182

11891183
// With the appropriate no-wrap constraint, remove a multiply by the divisor
11901184
// after peeking through another divide:

llvm/test/Transforms/InstCombine/div-shift.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,3 +1280,17 @@ entry:
12801280
%div = sdiv i32 %lhs, %rhs
12811281
ret i32 %div
12821282
}
1283+
1284+
@a = external global i32
1285+
define i32 @pr69291() {
1286+
; CHECK-LABEL: @pr69291(
1287+
; CHECK-NEXT: entry:
1288+
; CHECK-NEXT: ret i32 1
1289+
;
1290+
entry:
1291+
%conv = load i32, ptr @a, align 1
1292+
%add = shl nuw nsw i32 %conv, 1
1293+
%add2 = shl nuw nsw i32 %conv, 1
1294+
%div = sdiv i32 %add, %add2
1295+
ret i32 %div
1296+
}

0 commit comments

Comments
 (0)