Skip to content

Commit b359b50

Browse files
committed
Handle non neg case
1 parent 1423a4f commit b359b50

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp

Lines changed: 28 additions & 7 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_ADD: {
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+
19631969
Register Src1 = MI.getOperand(1).getReg();
19641970
unsigned Src1NumSignBits =
19651971
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;
1972+
if (Src1NumSignBits == 1)
1973+
return 1; // Early Out.
1974+
1975+
// Special case decrementing a value (ADD X, -1):
1976+
KnownBits Known2 = getKnownBits(Src2, DemandedElts, Depth);
1977+
if (Known2.isAllOnes()) {
1978+
KnownBits Known1 = getKnownBits(Src1, DemandedElts, Depth);
1979+
// If the input is known to be 0 or 1, the output is 0/-1, which is all
1980+
// sign bits set.
1981+
if ((Known1.Zero | 1).isAllOnes())
1982+
return TyBits;
1983+
1984+
// If the input is known to be positive (the sign bit is known clear),
1985+
// the output of the NEG has the same number of sign bits as the input.
1986+
if (Known1.isNonNegative())
1987+
return Src1NumSignBits;
1988+
1989+
// Otherwise, we treat this like an ADD.
19731990
}
1991+
1992+
// Add 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/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5058,8 +5058,7 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
50585058
break;
50595059
case ISD::ADD:
50605060
case ISD::ADDC:
5061-
// Add can have at most one carry bit. Thus we know that the output
5062-
// is, at worst, one more bit than the inputs.
5061+
// TODO: Move Operand 1 check before Operand 0 check
50635062
Tmp = ComputeNumSignBits(Op.getOperand(0), DemandedElts, Depth + 1);
50645063
if (Tmp == 1) return 1; // Early out.
50655064

@@ -5083,6 +5082,9 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
50835082

50845083
Tmp2 = ComputeNumSignBits(Op.getOperand(1), DemandedElts, Depth + 1);
50855084
if (Tmp2 == 1) return 1; // Early out.
5085+
5086+
// Add can have at most one carry bit. Thus we know that the output
5087+
// is, at worst, one more bit than the inputs.
50865088
return std::min(Tmp, Tmp2) - 1;
50875089
case ISD::SUB:
50885090
Tmp2 = ComputeNumSignBits(Op.getOperand(1), DemandedElts, Depth + 1);

llvm/test/CodeGen/AArch64/GlobalISel/knownbits-add.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:11111111 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:1111111111111111 SignBits:16
156156
; CHECK-NEXT: %5:_ KnownBits:1111111111111111 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)