mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
[ValueTracking] Fix PR23011.
Summary: `ComputeNumSignBits` returns incorrect results for `srem` instructions. This change fixes the issue and adds a test case. Reviewers: nadav, nicholas, atrick Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8600 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233225 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
eb32048f80
commit
93d88192a2
@ -1914,8 +1914,9 @@ unsigned ComputeNumSignBits(Value *V, const DataLayout &DL, unsigned Depth,
|
|||||||
|
|
||||||
case Instruction::SRem: {
|
case Instruction::SRem: {
|
||||||
const APInt *Denominator;
|
const APInt *Denominator;
|
||||||
// srem X, C -> we know that the result is within 0..C-1 when C is a
|
// srem X, C -> we know that the result is within [-C+1,C) when C is a
|
||||||
// positive constant and the sign bits are at most TypeBits - log2(C).
|
// positive constant. This let us put a lower bound on the number of sign
|
||||||
|
// bits.
|
||||||
if (match(U->getOperand(1), m_APInt(Denominator))) {
|
if (match(U->getOperand(1), m_APInt(Denominator))) {
|
||||||
|
|
||||||
// Ignore non-positive denominator.
|
// Ignore non-positive denominator.
|
||||||
@ -1928,11 +1929,19 @@ unsigned ComputeNumSignBits(Value *V, const DataLayout &DL, unsigned Depth,
|
|||||||
ComputeNumSignBits(U->getOperand(0), DL, Depth + 1, Q);
|
ComputeNumSignBits(U->getOperand(0), DL, Depth + 1, Q);
|
||||||
|
|
||||||
// Calculate the leading sign bit constraints by examining the
|
// Calculate the leading sign bit constraints by examining the
|
||||||
// denominator. The remainder is in the range 0..C-1, which is
|
// denominator. Given that the denominator is positive, there are two
|
||||||
// calculated by the log2(denominator). The sign bits are the bit-width
|
// cases:
|
||||||
// minus this value. The result of this subtraction has to be positive.
|
//
|
||||||
unsigned ResBits = TyBits - Denominator->logBase2();
|
// 1. the numerator is positive. The result range is [0,C) and [0,C) u<
|
||||||
|
// (1 << ceilLogBase2(C)).
|
||||||
|
//
|
||||||
|
// 2. the numerator is negative. Then the result range is (-C,0] and
|
||||||
|
// integers in (-C,0] are either 0 or >u (-1 << ceilLogBase2(C)).
|
||||||
|
//
|
||||||
|
// Thus a lower bound on the number of sign bits is `TyBits -
|
||||||
|
// ceilLogBase2(C)`.
|
||||||
|
|
||||||
|
unsigned ResBits = TyBits - Denominator->ceilLogBase2();
|
||||||
return std::max(NumrBits, ResBits);
|
return std::max(NumrBits, ResBits);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
15
test/Analysis/ValueTracking/pr23011.ll
Normal file
15
test/Analysis/ValueTracking/pr23011.ll
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
; RUN: opt -indvars -S < %s | FileCheck %s
|
||||||
|
|
||||||
|
declare { i8, i1 } @llvm.smul.with.overflow.i8(i8, i8) nounwind readnone
|
||||||
|
|
||||||
|
define i1 @test1(i8 %x) {
|
||||||
|
entry:
|
||||||
|
; CHECK-LABEL: @test1
|
||||||
|
%rem = srem i8 %x, 15
|
||||||
|
%t = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %rem, i8 %rem)
|
||||||
|
; CHECK: %t = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %rem, i8 %rem)
|
||||||
|
; CHECK: %obit = extractvalue { i8, i1 } %t, 1
|
||||||
|
; CHECK: ret i1 %obit
|
||||||
|
%obit = extractvalue { i8, i1 } %t, 1
|
||||||
|
ret i1 %obit
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user