diff options
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 10 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/vector-udiv.ll | 49 |
2 files changed, 55 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 9efc797d464..9bbabd9203b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -1081,12 +1081,14 @@ static Instruction *foldUDivShl(Value *Op0, Value *Op1, const BinaryOperator &I, if (!match(Op1, m_ZExt(m_Value(ShiftLeft)))) ShiftLeft = Op1; - const APInt *CI; + Constant *CI; Value *N; - if (!match(ShiftLeft, m_Shl(m_APInt(CI), m_Value(N)))) + if (!match(ShiftLeft, m_Shl(m_Constant(CI), m_Value(N)))) llvm_unreachable("match should never fail here!"); - if (*CI != 1) - N = IC.Builder.CreateAdd(N, ConstantInt::get(N->getType(), CI->logBase2())); + Constant *Log2Base = getLogBase2(N->getType(), CI); + if (!Log2Base) + llvm_unreachable("getLogBase2 should never fail here!"); + N = IC.Builder.CreateAdd(N, Log2Base); if (Op1 != ShiftLeft) N = IC.Builder.CreateZExt(N, Op1->getType()); BinaryOperator *LShr = BinaryOperator::CreateLShr(Op0, N); diff --git a/llvm/test/Transforms/InstCombine/vector-udiv.ll b/llvm/test/Transforms/InstCombine/vector-udiv.ll index 5052661ee4e..4da964268a6 100644 --- a/llvm/test/Transforms/InstCombine/vector-udiv.ll +++ b/llvm/test/Transforms/InstCombine/vector-udiv.ll @@ -19,3 +19,52 @@ define <4 x i32> @test_v4i32_const_pow2(<4 x i32> %a0) { ret <4 x i32> %1 } +; X udiv (C1 << N), where C1 is "1<<C2" --> X >> (N+C2) +define <4 x i32> @test_v4i32_shl_splatconst_pow2(<4 x i32> %a0, <4 x i32> %a1) { +; CHECK-LABEL: @test_v4i32_shl_splatconst_pow2( +; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[A1:%.*]], <i32 2, i32 2, i32 2, i32 2> +; CHECK-NEXT: [[TMP2:%.*]] = lshr <4 x i32> [[A0:%.*]], [[TMP1]] +; CHECK-NEXT: ret <4 x i32> [[TMP2]] +; + %1 = shl <4 x i32> <i32 4, i32 4, i32 4, i32 4>, %a1 + %2 = udiv <4 x i32> %a0, %1 + ret <4 x i32> %2 +} + +define <4 x i32> @test_v4i32_shl_const_pow2(<4 x i32> %a0, <4 x i32> %a1) { +; CHECK-LABEL: @test_v4i32_shl_const_pow2( +; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[A1:%.*]], <i32 2, i32 3, i32 4, i32 5> +; CHECK-NEXT: [[TMP2:%.*]] = lshr <4 x i32> [[A0:%.*]], [[TMP1]] +; CHECK-NEXT: ret <4 x i32> [[TMP2]] +; + %1 = shl <4 x i32> <i32 4, i32 8, i32 16, i32 32>, %a1 + %2 = udiv <4 x i32> %a0, %1 + ret <4 x i32> %2 +} + +; X udiv (zext (C1 << N)), where C1 is "1<<C2" --> X >> (N+C2) +define <4 x i32> @test_v4i32_zext_shl_splatconst_pow2(<4 x i32> %a0, <4 x i16> %a1) { +; CHECK-LABEL: @test_v4i32_zext_shl_splatconst_pow2( +; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i16> [[A1:%.*]], <i16 2, i16 2, i16 2, i16 2> +; CHECK-NEXT: [[TMP2:%.*]] = zext <4 x i16> [[TMP1]] to <4 x i32> +; CHECK-NEXT: [[TMP3:%.*]] = lshr <4 x i32> [[A0:%.*]], [[TMP2]] +; CHECK-NEXT: ret <4 x i32> [[TMP3]] +; + %1 = shl <4 x i16> <i16 4, i16 4, i16 4, i16 4>, %a1 + %2 = zext <4 x i16> %1 to <4 x i32> + %3 = udiv <4 x i32> %a0, %2 + ret <4 x i32> %3 +} + +define <4 x i32> @test_v4i32_zext_shl_const_pow2(<4 x i32> %a0, <4 x i16> %a1) { +; CHECK-LABEL: @test_v4i32_zext_shl_const_pow2( +; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i16> [[A1:%.*]], <i16 2, i16 3, i16 4, i16 5> +; CHECK-NEXT: [[TMP2:%.*]] = zext <4 x i16> [[TMP1]] to <4 x i32> +; CHECK-NEXT: [[TMP3:%.*]] = lshr <4 x i32> [[A0:%.*]], [[TMP2]] +; CHECK-NEXT: ret <4 x i32> [[TMP3]] +; + %1 = shl <4 x i16> <i16 4, i16 8, i16 16, i16 32>, %a1 + %2 = zext <4 x i16> %1 to <4 x i32> + %3 = udiv <4 x i32> %a0, %2 + ret <4 x i32> %3 +} |