Skip to content

Commit 3fee3e8

Browse files
authored
KnownBits: refine srem for high-bits (#109121)
KnownBits::srem does not correctly set the leader zero-bits, omitting the fact that LHS may be known-negative or known-non-negative. Fix this. Alive2 proof: https://alive2.llvm.org/ce/z/Ugh-Dq
1 parent 5cc64bf commit 3fee3e8

File tree

3 files changed

+17
-28
lines changed

3 files changed

+17
-28
lines changed

llvm/lib/Support/KnownBits.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,9 +1075,13 @@ KnownBits KnownBits::srem(const KnownBits &LHS, const KnownBits &RHS) {
10751075

10761076
// The sign bit is the LHS's sign bit, except when the result of the
10771077
// remainder is zero. The magnitude of the result should be less than or
1078-
// equal to the magnitude of the LHS. Therefore any leading zeros that exist
1079-
// in the left hand side must also exist in the result.
1080-
Known.Zero.setHighBits(LHS.countMinLeadingZeros());
1078+
// equal to the magnitude of either operand.
1079+
if (LHS.isNegative() && Known.isNonZero())
1080+
Known.One.setHighBits(
1081+
std::max(LHS.countMinLeadingOnes(), RHS.countMinSignBits()));
1082+
else if (LHS.isNonNegative())
1083+
Known.Zero.setHighBits(
1084+
std::max(LHS.countMinLeadingZeros(), RHS.countMinSignBits()));
10811085
return Known;
10821086
}
10831087

llvm/test/Analysis/ValueTracking/knownbits-rem.ll

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,7 @@ define i8 @srem_low_bits_know2(i8 %xx, i8 %yy) {
104104

105105
define i8 @srem_high_bits_know(i8 %xx, i8 %yy) {
106106
; CHECK-LABEL: @srem_high_bits_know(
107-
; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], -2
108-
; CHECK-NEXT: [[Y:%.*]] = and i8 [[YY:%.*]], -4
109-
; CHECK-NEXT: [[REM:%.*]] = srem i8 [[X]], [[Y]]
110-
; CHECK-NEXT: [[R:%.*]] = and i8 [[REM]], -2
111-
; CHECK-NEXT: ret i8 [[R]]
107+
; CHECK-NEXT: ret i8 -2
112108
;
113109
%x = or i8 %xx, -2
114110
%y = and i8 %yy, -4
@@ -119,11 +115,7 @@ define i8 @srem_high_bits_know(i8 %xx, i8 %yy) {
119115

120116
define i8 @srem_high_bits_know2(i8 %xx, i8 %yy) {
121117
; CHECK-LABEL: @srem_high_bits_know2(
122-
; CHECK-NEXT: [[X:%.*]] = and i8 [[XX:%.*]], 13
123-
; CHECK-NEXT: [[Y:%.*]] = or i8 [[YY:%.*]], -4
124-
; CHECK-NEXT: [[REM:%.*]] = srem i8 [[X]], [[Y]]
125-
; CHECK-NEXT: [[R:%.*]] = and i8 [[REM]], 8
126-
; CHECK-NEXT: ret i8 [[R]]
118+
; CHECK-NEXT: ret i8 0
127119
;
128120
%x = and i8 %xx, 13
129121
%y = or i8 %yy, -4
@@ -134,11 +126,7 @@ define i8 @srem_high_bits_know2(i8 %xx, i8 %yy) {
134126

135127
define i8 @srem_high_bits_know3(i8 %xx, i8 %yy) {
136128
; CHECK-LABEL: @srem_high_bits_know3(
137-
; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], -13
138-
; CHECK-NEXT: [[Y:%.*]] = and i8 [[YY:%.*]], 4
139-
; CHECK-NEXT: [[REM:%.*]] = srem i8 [[X]], [[Y]]
140-
; CHECK-NEXT: [[R:%.*]] = and i8 [[REM]], 8
141-
; CHECK-NEXT: ret i8 [[R]]
129+
; CHECK-NEXT: ret i8 8
142130
;
143131
%x = or i8 %xx, -13
144132
%y = and i8 %yy, 4

llvm/test/CodeGen/ARM/select-imm.ll

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -655,14 +655,11 @@ define i1 @t10() {
655655
; V8MBASE-NEXT: .pad #8
656656
; V8MBASE-NEXT: sub sp, #8
657657
; V8MBASE-NEXT: movs r0, #7
658-
; V8MBASE-NEXT: mvns r0, r0
659-
; V8MBASE-NEXT: str r0, [sp]
660-
; V8MBASE-NEXT: adds r1, r0, #5
661-
; V8MBASE-NEXT: str r1, [sp, #4]
662-
; V8MBASE-NEXT: sdiv r2, r1, r0
663-
; V8MBASE-NEXT: muls r2, r0, r2
664-
; V8MBASE-NEXT: subs r0, r1, r2
665-
; V8MBASE-NEXT: subs r1, r0, r1
658+
; V8MBASE-NEXT: mvns r1, r0
659+
; V8MBASE-NEXT: str r1, [sp]
660+
; V8MBASE-NEXT: adds r0, r1, #5
661+
; V8MBASE-NEXT: str r0, [sp, #4]
662+
; V8MBASE-NEXT: adds r1, #8
666663
; V8MBASE-NEXT: rsbs r0, r1, #0
667664
; V8MBASE-NEXT: adcs r0, r1
668665
; V8MBASE-NEXT: add sp, #8
@@ -719,7 +716,7 @@ define i1 @t11() {
719716
; ARMT2-NEXT: and r1, r1, r2
720717
; ARMT2-NEXT: orr r0, r1, r0
721718
; ARMT2-NEXT: str r0, [sp]
722-
; ARMT2-NEXT: bfc r0, #12, #20
719+
; ARMT2-NEXT: and r0, r0, #15
723720
; ARMT2-NEXT: sub r0, r0, #3
724721
; ARMT2-NEXT: clz r0, r0
725722
; ARMT2-NEXT: lsr r0, r0, #5
@@ -781,7 +778,7 @@ define i1 @t11() {
781778
; THUMB2-NEXT: ands r1, r2
782779
; THUMB2-NEXT: orrs r0, r1
783780
; THUMB2-NEXT: str r0, [sp]
784-
; THUMB2-NEXT: bfc r0, #12, #20
781+
; THUMB2-NEXT: and r0, r0, #15
785782
; THUMB2-NEXT: subs r0, #3
786783
; THUMB2-NEXT: clz r0, r0
787784
; THUMB2-NEXT: lsrs r0, r0, #5

0 commit comments

Comments
 (0)