Forking this off from bug 49543 - we can eliminate an intermediate cast in a sequence like this by using 'ashr' to replicate the signbit: define i64 @src(i32 %a0) { %a = lshr i32 %a0, 24 %b = trunc i32 %a to i8 %c = sext i8 %b to i64 ret i64 %c } define i64 @tgt(i32 %a0) { %a = ashr i32 %a0, 24 %c = sext i32 %a to i64 ret i64 %c }
We should also handle the case where the initial width is bigger than the destination: define i26 @src(i32 %a0) { %a = lshr i32 %a0, 24 %b = trunc i32 %a to i8 %c = sext i8 %b to i26 ret i26 %c } Instead of a sext, we need to trunc: define i26 @tgt(i32 %a0) { %a = ashr i32 %a0, 24 %c = trunc i32 %a to i26 ret i26 %c } We already handle the pattern where initial width == dest width by converting to shifts (lshr cancels out shl in that case).
(In reply to Sanjay Patel from comment #1) > <...> Also see https://reviews.llvm.org/rG41b71f718b94c6f12bbaa670e97cabb070308ed2
(In reply to Roman Lebedev from comment #2) > Also see https://reviews.llvm.org/rG41b71f718b94c6f12bbaa670e97cabb070308ed2 Thanks! That goes a bit further than what I had drafted, so I pushed extra tests and a smaller patch as a first step: https://reviews.llvm.org/rG8937450e8581 https://reviews.llvm.org/rG23a116c8c446 Hopefully, the basic cases here are fixed now. I left TODO comments on the tests for the remaining part.