[LLVMdev] Preserving NSW/NUW bits

Chad Rosier mcrosier at codeaurora.org
Wed Sep 3 10:19:45 PDT 2014


Thanks for the details, David.  More comments below.

> On Tue, Sep 2, 2014 at 4:16 PM, David Majnemer <david.majnemer at gmail.com>
> wrote:
>
>> So, the trunc makes this transform a bit questionable because you have
>> to
>> reason about bits in the middle of your value.
>>
>> Consider the following input values:
>> %indvars.iv = 0x........7fffffff
>> %0 = 0x8......1
>>
>> Consider the following values in the 'before' case:
>> %2 = 0x........7fffffff
>> %indvars.iv.next = 0x........80000000
>> %tmp = 0x7fffffff
>> %cmp = false
>>
>> This results in the following values in the 'after' case:
>> %indvars.iv.next = 0x........80000000
>> %tmp = 0x80000000
>> %cmp = true
>>
>> Regardless of whether or not you propagate nsw/nuw, the transform is
>> currently unsound.
>>
>> The transform is sound if %indvars.iv has a sufficiently large number of
>> signbits.
>> e.x.
>> %indvars.iv = sext i31 %invdars.actual to i64

This is in fact the case.  IndVarSimplicifaction is sign-extending the
induction variable.  I also have a change that will widen the compare to
remove the trunc, but this is still a WIP.  With all of this in place I'm
hoping InstCombine will do what I want and remove the extra 'add i64
%indvars.iv.next, -1.'

 Chad

>>
>> If this precondition holds, any existing nsw or nuw flags should still
>> hold.
>>
>
> Some other interesting things spring to mind.
> If either (%indvars.iv & (1 << 31)) == 1 or if (%indvars.iv & (1 << 31))
> ==
> (%indvars.iv & (1 << 30)), then the transform is safe; I'm not immediately
> sure about nuw or nsw.
>
>
>>
>>
>>
>> On Tue, Sep 2, 2014 at 3:22 PM, Chad Rosier <mcrosier at codeaurora.org>
>> wrote:
>>
>>> David/All,
>>> Just a quick question about NSW/NUW bits, if you've got a second.  I
>>> noticed you've been doing a little work on this as of late.
>>>
>>> I have a bit of code that looks like the following:
>>>
>>>   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
>>>   %2 = add i64 %indvars.iv.next, -1
>>>   %tmp = trunc i64 %2 to i32
>>>   %cmp = icmp slt i32 %tmp, %0
>>>   br i1 %cmp, label %for.body, label %for.end.loopexit
>>>
>>> I'm trying to fold the 2nd add instruction into the compare by changing
>>> the condition from from 'slt' to 'sle':
>>>
>>>   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
>>>   %tmp = trunc i64 %indvars.iv.next to i32
>>>   %cmp = icmp sle i32 %tmp, %0
>>>   br i1 %cmp, label %for.body, label %for.end.loopexit
>>>
>>> However, AFAICT the NSW bits must be set.  In what cases can we
>>> propagate
>>> the NSW bit from the first add to the second, if any?  If a case
>>> exists,
>>> can this be handled by the WillNotOverflowSignedAdd function?
>>>
>>>  Chad
>>>
>>>
>>
>





More information about the llvm-dev mailing list