[PATCH] D30184: [IR] Add a Instruction::dropPoisonGeneratingFlags helper

Sanjoy Das via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 20 23:31:18 PST 2017


sanjoy added a comment.

In https://reviews.llvm.org/D30184#681956, @majnemer wrote:

> Out of curiosity, why not use `clearSubclassOptionalData` in place of wherever you intend to use `dropPoisonGeneratingFlags`?


That seems like a layering problem -- there is no guarantee (is there?) that the bits in `SubclassOptionalData` correspond to poison.  We could conceivably add bits there in the future that (say) denote some probabilistic information (the result of this `add` is probably positive).  That would satisfy the contract of `SubclassOptionalData`, but would not require to be dropped in `dropPoisonGeneratingFlags`.



================
Comment at: lib/IR/Instruction.cpp:143
+  case Instruction::GetElementPtr:
+    cast<GetElementPtrInst>(this)->setIsInBounds(false);
+    break;
----------------
majnemer wrote:
> sanjoy wrote:
> > majnemer wrote:
> > > What about `inrange`?
> > Reading the language ref, `inrange` does not fit into the poison mould very well.
> > 
> > Say you have
> > 
> > ```
> > struct S {
> >   struct {
> >     int arr[2];
> >   } t0;
> >   struct {
> >     int arr[2];
> >   } t1;
> > };
> > ```
> > 
> > which in IR would be
> > 
> > ```
> > %struct.S = type { %struct.anon, %struct.anon.0 }
> > %struct.anon = type { [2 x i32] }
> > %struct.anon.0 = type { [2 x i32] }
> > 
> > ```
> > 
> > if I'm reading the ref correctly (am I?), then in
> > 
> > ```
> > %a = getelementptr %struct.S, %struct.S* %0, i64 0, inrange i32 0, i32 0, i64 0
> > %b = getelementptr i32, i32* %a, i32 2
> > %c = load i32, i32* %b
> > ```
> > 
> > the load has undefined behavior.  In the poison view of things, we'd like to say that either `%a` or `%b` was poison (with the caveat that `%b` can be generating poison itself, or it could have just passed along the poison it got from `%a`).  Now `%a` cannot be poison because we want to allow loads and stores through it as usual, which means `%b` was poison.  But that's odd -- `%b` took a non-poison value as input which it converted into poison by normal wrapping arithmetic (and there is no flag I can strip from that GEP to have it produce a safe (non-poison) value).  This means with `inrange` in the picture, non-`inbounds`, non-`inrange` GEPs are no longer "just" additions, multiplications and sign extends.
> > 
> Hmm, according to the docs:
> > Note that the inrange keyword is currently only allowed in constant getelementptr expressions.
> 
> We can punt on this I guess.
Okay.

I think the problem above still applies (i.e. right now in LLVM a non-flagged GEP can produce poison), but I do like punting.  :)


https://reviews.llvm.org/D30184





More information about the llvm-commits mailing list