Index: InstCombineCasts.cpp =================================================================== --- InstCombineCasts.cpp +++ InstCombineCasts.cpp @@ -1254,6 +1254,21 @@ return BinaryOperator::CreateAShr(A, ShAmtV); } + // Transform: + // %a = lshr i32 %i, 16 + // %b = trunc i32 %a to i16 + // %c = sext i16 %b to i32 + // To: + // %c = ashr i32 %i, 16 + const APInt *SA = nullptr; + if (match(Src, m_OneUse(m_Trunc( m_OneUse(m_LShr(m_Value(A), m_APInt(SA)))))) && + A->getType() == CI.getType()) { + unsigned SextSize = CI.getType()->getScalarSizeInBits(); + unsigned TruncSize = Src->getType()->getScalarSizeInBits(); + if (*SA == SextSize - TruncSize) + return BinaryOperator::CreateAShr(A, ConstantInt::get(CI.getContext(), *SA)); + } + return nullptr; } Index: cast.ll =================================================================== --- cast.ll +++ cast.ll @@ -1432,3 +1432,13 @@ %tmp6 = bitcast <4 x half> to <2 x i32> ret <2 x i32> %tmp6 } + +define i32 @test91(i32 %i) { +; CHECK-LABEL: @test91( +; CHECK: ashr +; CHECK: ret + %a = lshr i32 %i, 16 + %b = trunc i32 %a to i16 + %c = sext i16 %b to i32 + ret i32 %c +}