Skip to content

Commit 34ba864

Browse files
bjopeyuxuanchen1997
authored andcommitted
[InstCombine] Add tests cases related to demanded use bits for ashr
Summary: When trying to improve value tracking in #97693 some regressions was found due to a "weirdness" in simplify demanded use bits for ashr. Normally an ashr is replaced by lshr when the shifted in bits aren't demanded. Some years ago (see commit 22178dd) there was a test case motivating to keep the ashr when any sign bit (besides the shifted in bits) was demanded. The weird part about it is that the better we get at analysing known sign bits, the less likely it is that we canonicalize from ashr to lshr. That makes it hard to tune other combines to work based on the canonicalization, as well as possibly resulting in unexpected regressions when improving value tracking. This patch adds a test case for which it would be better to canonicalize ashr into lshr when possible. Worth mentioning is also that reverting 22178dd doesn't seem to cause regressions in any other lit tests (not even the one added in 22178dd). Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60250955
1 parent 0c58278 commit 34ba864

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

llvm/test/Transforms/InstCombine/ashr-demand.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,39 @@ define <2 x i32> @srem2_ashr_mask_vector_nonconstant(<2 x i32> %a0, <2 x i32> %a
5252
%mask = and <2 x i32> %ashr, <i32 2, i32 2>
5353
ret <2 x i32> %mask
5454
}
55+
56+
57+
; If it does not matter if we do ashr or lshr, then we canonicalize to lshr.
58+
59+
define i16 @ashr_can_be_lshr(i32 %a) {
60+
; CHECK-LABEL: @ashr_can_be_lshr(
61+
; CHECK-NEXT: [[ASHR:%.*]] = lshr exact i32 [[A:%.*]], 16
62+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i32 [[ASHR]] to i16
63+
; CHECK-NEXT: ret i16 [[TRUNC]]
64+
;
65+
%ashr = ashr exact i32 %a, 16
66+
%trunc = trunc nsw i32 %ashr to i16
67+
ret i16 %trunc
68+
}
69+
70+
; Historically SimplifyDemandedUseBits skipped replacing ashr with lshr here
71+
; due to known sign bits analysis indicating that %ashr had more than 33 sign
72+
; bits. It does however seem weird not to always canonicalize to lshr when
73+
; possible, and in this case rewriting into lshr would trigger further
74+
; optimizations.
75+
define i32 @ashr_can_be_lshr_2(i32 %a) {
76+
; CHECK-LABEL: @ashr_can_be_lshr_2(
77+
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[A:%.*]], 1056964608
78+
; CHECK-NEXT: [[OR:%.*]] = zext i32 [[TMP1]] to i64
79+
; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[OR]], 34
80+
; CHECK-NEXT: [[ASHR:%.*]] = ashr exact i64 [[SHL]], 32
81+
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nsw i64 [[ASHR]] to i32
82+
; CHECK-NEXT: ret i32 [[TRUNC]]
83+
;
84+
%ext = zext i32 %a to i64
85+
%or = or i64 %ext, 4278190080
86+
%shl = shl i64 %or, 34
87+
%ashr = ashr exact i64 %shl, 32
88+
%trunc = trunc nsw i64 %ashr to i32
89+
ret i32 %trunc
90+
}

0 commit comments

Comments
 (0)