[PATCH] InstCombine: constant comparison involving ashr is wrongly simplified (PR20945).
Duncan P. N. Exon Smith
dexonsmith at apple.com
Tue Sep 16 13:19:53 PDT 2014
> On 2014-Sep-16, at 12:58, Andrea Di Biagio <Andrea_DiBiagio at sn.scee.net> wrote:
>
> Hi Duncan,
>
> Here is an updated patch which I think/hope addresses all your comments.
>
> There is one main difference with respect to what you suggested (see below)
>
>> Then change this to:
>>
>> if (!IsNegative && AP1.ugt(AP2))
>> // Right-shifting won't increase the magnitude.
>> return getConstant(false);
>>
>
> That check should also take into account the case where 'IsAShr' is false, AP2 is negative and AP1 is positive.
I don't think that case exists. `lshr` deals with unsigned numbers.
There's no such thing as a negative unsigned number. For `lshr`, it's
easier to think about numbers as bitstrings.
> Otherwise, it would have failed for the following case:
>
> {code}
> define i1 @foo(i8 %a) {
> %shr = lshr exact i8 -128, %a
> %cmp = icmp eq i8 %shr, 1
> ret i1 %cmp
> }
> {code}
In binary, this translates to:
define i1 @foo(i8 %a) {
%shr = lshr exact i8 0b10000000, %a
%cmp = icmp eq i8 %shr, 0b00000001
ret i1 %cmp
}
AFAICT, this transformation should produce:
define i1 @foo(i8 %a) {
%cmp = icmp eq i8 %a, 7
ret i1 %cmp
}
Does it do something else? What? Can you add this as a testcase?
>
> Please let me know what you think.
> Thanks,
> Andrea
>
> http://reviews.llvm.org/D5356
>
> Files:
> lib/Transforms/InstCombine/InstCombineCompares.cpp
> test/Transforms/InstCombine/icmp-shr.ll
> <D5356.13759.patch>
>
> + if (!IsAShr) {
> + bool IsAP1Negative = AP1.isNegative();
> + bool IsAP2Negative = AP2.isNegative();
> + if (IsAP1Negative && IsAP2Negative)
> + // Logical shift by a non-zero quantity always changes the sign bit of a
> + // negative number.
> + return getConstant(false);
> + if (IsAP1Negative)
> + // Logical shift never affects the sign of a positive number.
> + return getConstant(false);
> + if (!IsAP2Negative && AP1.ugt(AP2))
> + // Right-shifting will not increase the value.
> + return getConstant(false);
> + }
This new logic doesn't make sense to me. Note that `isNegative()` just
tells you whether the MSB is set to 1. How is the MSB relevant here?
(It certainly isn't a sign bit.)
More information about the llvm-commits
mailing list