Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -992,6 +992,12 @@ return X; } + // (X << 1) / X -> 2 + if ((IsSigned && match(Op0, m_NSWShl(m_Specific(Op1), m_One()))) || + (!IsSigned && match(Op0, m_Shl(m_Specific(Op1), m_One())))) { + return ConstantInt::get(Op0->getType(), 2); + } + // (X rem Y) / Y -> 0 if ((IsSigned && match(Op0, m_SRem(m_Value(), m_Specific(Op1)))) || (!IsSigned && match(Op0, m_URem(m_Value(), m_Specific(Op1))))) Index: test/Transforms/InstSimplify/div.ll =================================================================== --- test/Transforms/InstSimplify/div.ll +++ test/Transforms/InstSimplify/div.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -instsimplify -S | FileCheck %s ; Division-by-zero is undef. UB in any vector lane means the whole op is undef. @@ -134,4 +135,22 @@ ret i32 %urem } +define i32 @sdiv_nsw_doublex_x(i32 %x) { +; CHECK-LABEL: @sdiv_nsw_doublex_x( +; CHECK-NEXT: ret i32 2 +; + %add = shl nsw i32 %x, 1 + %div = sdiv i32 %add, %x + ret i32 %div +} + +define i32 @udiv_doublex_x(i32 %x) { +; CHECK-LABEL: @udiv_doublex_x( +; CHECK-NEXT: ret i32 2 +; + %add = shl i32 %x, 1 + %div = udiv i32 %add, %x + ret i32 %div +} + !0 = !{i32 0, i32 3}