Wrong value for sext i1 true in BasicAliasAnalysis

Andrew Trick atrick at apple.com
Tue Dec 16 14:02:13 PST 2014


> On Dec 16, 2014, at 12:03 PM, Hal Finkel <hfinkel at anl.gov> wrote:
> 
> ----- Original Message -----
>> From: "Nicholas White" <n.j.white at gmail.com>
>> To: "Hal Finkel" <hfinkel at anl.gov>
>> Cc: "Yin Ma" <yinma at codeaurora.org>, "Commit Messages and Patches for LLVM" <llvm-commits at cs.uiuc.edu>, "Arnold
>> Schwaighofer" <aschwaighofer at apple.com>
>> Sent: Tuesday, December 16, 2014 11:46:27 AM
>> Subject: Re: Wrong value for sext i1 true in BasicAliasAnalysis
>> 
>> 
>> 
>> Hm, this turns out to be quite a bit more complicated than I thought.
>> Consider the test IR below - different wrapping flags (nsw, nuw) on
>> the add and sub functions give different guarantees, so while %c
>> MustAlias to %a, %b and %d only PartialAlias to %a as if the
>> arithmetic wraps then %b and %d just NoAlias %a. I think
>> GetLinearExpression needs to know a bit more about modular
>> arithmetic, and when it's safe to ignore extensions (e.g. a "zext"
>> of a value produced by "add nsw nuw" can be ignored). I've made a
>> very conservative patch here: http://reviews.llvm.org/D6682 that
>> refuses to process any BinaryOps if the result is going to be
>> extended in some way (the Extension == EK_NotExtended check) and
>> have added the tests cases on this thread to it. However, the patch
>> causes "make check" to fail as it makes the BasicAA pass returns
>> PartialAlias results where the current tip returns NoAlias. I can't
>> find any library functions that do symbolic modular arithmetic in
>> the codebase (would ValueTracking be the logical place for this?),
>> so I'm going to work a bit more on the logic in GetLinearExpression.
>> Any ideas would be greatly appreciated :)
> 
> Maybe the code in SCEV that does something like what you need. Andy?

SCEV expressions are partitioned into subexpressions of the same bitwidth, with sext/zext/trunc in between. It doesn't really run into those issues. But maybe some of the delinearization work is relevant here. I'm not sure.

Without saying how to fit this into BasicAA, I'll say that if you want to take advantage of NSW/NUW you just have to formulate your solution in terms of these facts:

NUW: zext(A+B) => zext(A)+zext(B)
NSW: sext(A+B) => sext(A)+sext(B)

(that’s what indvars IVWidening does)

Another useful fact is:
NSW: sext(C1 + (C2 * x)) => C1 + sext(C2 * x) if C1 < C2

(from SCEV getSignExtendExpr)

-Andy

> 
> -Hal
> 
>> 
>> Thanks -
>> 
>> Nick
>> 
>> 
>> define void @test_path_dependence(i32 %p, i8* %mem) {
>> %p.minus1 = add i32 %p, -1 ; this will always unsigned-wrap, unless
>> %p == 0
>> %p.minus1.64 = zext i32 %p.minus1 to i64
>> %p.64.again = add i64 %p.minus1.64, 1 ; either %p (if we wrapped) or
>> 4294967296 (if we didn't)
>> 
>> %p.nsw.nuw.minus1 = sub nsw nuw i32 %p, 1 ; as nuw we know %p >= 1
>> %p.nsw.nuw.minus1.64 = zext i32 %p.nsw.nuw.minus1 to i64
>> %p.nsw.nuw.64.again = add nsw nuw i64 %p.nsw.nuw.minus1.64, 1 ; ...so
>> always exactly %p
>> 
>> %p.nsw.minus1 = sub nsw i32 %p, 1 ; only nsw, so can only guarantee
>> %p != 0x10000000
>> %p.nsw.minus1.64 = zext i32 %p.nsw.minus1 to i64 ; when %p >
>> 0x10000000 (ie <= 0 as a signed number) then the zext will make this
>> a huge positive number
>> %p.nsw.64.again = add nsw i64 %p.nsw.minus1.64, 1 ; ...and so this is
>> very much != %p
>> 
>> %p.64 = zext i32 %p to i64
>> %a = getelementptr inbounds i8* %mem, i64 %p.64
>> %b = getelementptr inbounds i8* %mem, i64 %p.64.again
>> %c = getelementptr inbounds i8* %mem, i64 %p.nsw.nuw.64.again
>> %d = getelementptr inbounds i8* %mem, i64 %p.nsw.64.again
>> ret void
>> }
>> 
> 
> -- 
> Hal Finkel
> Assistant Computational Scientist
> Leadership Computing Facility
> Argonne National Laboratory





More information about the llvm-commits mailing list