diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -370,7 +370,9 @@ } if (match(V, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI)) { - int64_t Mult = int64_t(std::pow(int64_t(2), CI->getSExtValue())); + if (CI->getSExtValue() < 0 || CI->getSExtValue() >= 64) + return {V, IsKnownNonNegative}; + int64_t Mult = 1 << CI->getSExtValue(); auto Result = decompose(Op1, Preconditions, IsSigned, DL); Result.mul(Mult); return Result; diff --git a/llvm/test/Transforms/ConstraintElimination/shl.ll b/llvm/test/Transforms/ConstraintElimination/shl.ll --- a/llvm/test/Transforms/ConstraintElimination/shl.ll +++ b/llvm/test/Transforms/ConstraintElimination/shl.ll @@ -1232,7 +1232,7 @@ ; CHECK: main: ; CHECK-NEXT: [[TMP0:%.*]] = shl nuw nsw i64 [[START]], -1 ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i64 [[TMP0]], [[START]] -; CHECK-NEXT: ret i1 false +; CHECK-NEXT: ret i1 [[TMP1]] ; CHECK: exit: ; CHECK-NEXT: ret i1 false ; @@ -1255,7 +1255,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[SHL_UB:%.*]] = shl nuw nsw i256 0, 64 ; CHECK-NEXT: [[SHL_CMP:%.*]] = icmp uge i256 [[SHL_UB]], 0 -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: ret i1 [[SHL_CMP]] ; entry: %shl.ub = shl nuw nsw i256 0, 64 @@ -1268,7 +1268,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[SHL_UB:%.*]] = shl nuw nsw i256 0, 65 ; CHECK-NEXT: [[SHL_CMP:%.*]] = icmp uge i256 [[SHL_UB]], 0 -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: ret i1 [[SHL_CMP]] ; entry: %shl.ub = shl nuw nsw i256 0, 65