This is an archive of the discontinued LLVM Phabricator instance.

[IR] Add a Instruction::dropPoisonGeneratingFlags helper
ClosedPublic

Authored by sanjoy on Feb 20 2017, 10:22 PM.

Details

Summary

The helper will be used in a later change. This change itself is NFC
since the only user of this new function is its unit test.

Diff Detail

Repository
rL LLVM

Event Timeline

sanjoy created this revision.Feb 20 2017, 10:22 PM
majnemer added inline comments.Feb 20 2017, 10:24 PM
lib/IR/Instruction.cpp
126 ↗(On Diff #89162)

What about the FP operations?

143 ↗(On Diff #89162)

What about inrange?

sanjoy added inline comments.Feb 20 2017, 10:54 PM
lib/IR/Instruction.cpp
126 ↗(On Diff #89162)

None of the floating point operations are specified to generate poison. Are you suggesting that we interpret flags like nsz like we interpret nsw? If so, I think that's viable, but the docs need to change first. Personally I'd say that kind of stuff is blocked on integrating the new poison semantics into LLVM.

143 ↗(On Diff #89162)

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.

majnemer edited edge metadata.Feb 20 2017, 11:21 PM

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

lib/IR/Instruction.cpp
126 ↗(On Diff #89162)

Considering that we perform reassociation type optimizations based off those fast math flags, I think they are already defacto poison whether they want to be or not ;)

However, we shouldn't gate this change on that.

143 ↗(On Diff #89162)

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.

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.

lib/IR/Instruction.cpp
143 ↗(On Diff #89162)

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. :)

efriedma added inline comments.
lib/IR/Instruction.cpp
126 ↗(On Diff #89162)

Considering that we perform reassociation type optimizations based off those fast math flags, I think they are already defacto poison whether they want to be or not ;)

A "fast" fadd returns an arbitrary value each time it's executed, but that's not the same thing as poison. (There isn't any optimization reason to introduce undefined behavior into floating-point math, as far as I know.)

Ping - @majnemer @efriedma - are there any issues remaining in this patch that I need to address?

This revision is now accepted and ready to land.Feb 22 2017, 11:13 AM
This revision was automatically updated to reflect the committed changes.