Skip to content

Commit 12970b3

Browse files
committed
Handle Non Neg
1 parent 294002a commit 12970b3

File tree

2 files changed

+31
-10
lines changed

2 files changed

+31
-10
lines changed

llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1960,17 +1960,38 @@ unsigned GISelValueTracking::computeNumSignBits(Register R,
19601960
break;
19611961
}
19621962
case TargetOpcode::G_SUB: {
1963+
Register Src2 = MI.getOperand(2).getReg();
1964+
unsigned Src2NumSignBits =
1965+
computeNumSignBits(Src2, DemandedElts, Depth + 1);
1966+
if (Src2NumSignBits == 1)
1967+
return 1; // Early out.
1968+
1969+
// Handle NEG.
19631970
Register Src1 = MI.getOperand(1).getReg();
1971+
KnownBits Known1 = getKnownBits(Src1, DemandedElts, Depth);
1972+
if (Known1.isZero()) {
1973+
KnownBits Known2 = getKnownBits(Src2, DemandedElts, Depth);
1974+
// If the input is known to be 0 or 1, the output is 0/-1, which is all
1975+
// sign bits set.
1976+
if ((Known2.Zero | 1).isAllOnes())
1977+
return TyBits;
1978+
1979+
// If the input is known to be positive (the sign bit is known clear),
1980+
// the output of the NEG has the same number of sign bits as the input.
1981+
if (Known2.isNonNegative())
1982+
return Src2NumSignBits;
1983+
1984+
// Otherwise, we treat this like a SUB.
1985+
}
1986+
19641987
unsigned Src1NumSignBits =
19651988
computeNumSignBits(Src1, DemandedElts, Depth + 1);
1966-
if (Src1NumSignBits != 1) {
1967-
Register Src2 = MI.getOperand(2).getReg();
1968-
unsigned Src2NumSignBits =
1969-
computeNumSignBits(Src2, DemandedElts, Depth + 1);
1970-
if (Src2NumSignBits == 1)
1971-
return 1; // Early out.
1972-
FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1;
1973-
}
1989+
if (Src1NumSignBits == 1)
1990+
return 1; // Early Out.
1991+
1992+
// Sub can have at most one carry bit. Thus we know that the output
1993+
// is, at worst, one more bit than the inputs.
1994+
FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits) - 1;
19741995
break;
19751996
}
19761997
case TargetOpcode::G_FCMP:

llvm/test/CodeGen/AArch64/GlobalISel/knownbits-sub.mir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ body: |
8282
; CHECK-NEXT: %1:_ KnownBits:00001111 SignBits:4
8383
; CHECK-NEXT: %2:_ KnownBits:0000???? SignBits:4
8484
; CHECK-NEXT: %3:_ KnownBits:00000000 SignBits:8
85-
; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:3
85+
; CHECK-NEXT: %4:_ KnownBits:???????? SignBits:4
8686
%0:_(s8) = COPY $b0
8787
%1:_(s8) = G_CONSTANT i8 15
8888
%2:_(s8) = G_AND %0, %1
@@ -154,7 +154,7 @@ body: |
154154
; CHECK-NEXT: %3:_ KnownBits:00000000???????? SignBits:8
155155
; CHECK-NEXT: %4:_ KnownBits:0000000000000000 SignBits:16
156156
; CHECK-NEXT: %5:_ KnownBits:0000000000000000 SignBits:16
157-
; CHECK-NEXT: %6:_ KnownBits:???????????????? SignBits:7
157+
; CHECK-NEXT: %6:_ KnownBits:???????????????? SignBits:8
158158
%0:_(<4 x s16>) = COPY $d0
159159
%1:_(s16) = G_CONSTANT i16 255
160160
%2:_(<4 x s16>) = G_BUILD_VECTOR %1, %1, %1, %1

0 commit comments

Comments
 (0)