[PATCH] D13358: InstSimplify: Fold comparisons between allocas and arguments under certain circumstances
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 14:56:14 PDT 2015
hans marked 2 inline comments as done.
================
Comment at: lib/Analysis/InstructionSimplify.cpp:2130
@@ +2129,3 @@
+ // the alloca and argument compare unequal. To do this, the alloca mustn't
+ // be observed, and we must fold *all* comparisons between pointers based
+ // on the alloca and argument consistently.
----------------
sanjoy wrote:
> I have a question about this second bit -- do we have to ensure that we only *fold* such comparisons consistently, or do we have to ensure that they also evaluate consistently? IOW, say I have
>
> ```
> void f(i8* %arg) {
> i8* %val = alloca
> %t0 = %val == %arg
> ...
> %t1 = complex_xform(%val) == %arg
> ```
>
> such that `complex_xform(x) == x` always, but the compiler cannot prove that. Consequently we fold `%t0` to `false`, but don't fold `complex_xform(x) == x` at all, and it ends up evaluating to `true` at runtime.
>
> Are you relying on the fact that a `complex_xform` cannot be formed out of the operators you look through in `CanTrackAlluses`? I'd be more comfortable if you folded *all* comparisons based off of `%alloca` in one go.
Yes, exactly: the comparisons have to evaluate consistently, so we have to fold them all, and I'm relying on CanTrackAllUses (maybe not a great name actually) to ensure that we can do that.
I don't think I could fold all comparisons based on an %alloca in one go from InstSimplify as it's actually not changing the instruction, just returning a new value for it. Maybe there's a better place to do this?
On the other hand, I don't think multiple comparisons is very common. Maybe we should just bail out if we see another comparison? I'll do that for now.
================
Comment at: lib/Analysis/InstructionSimplify.cpp:2137
@@ +2136,3 @@
+
+ auto CanTrackAllUses = [DL](Value *V) {
+ unsigned MaxDepth = 16;
----------------
sanjoy wrote:
> Can this be rewritten to use `PointerMayBeCaptured`?
My check is much more conservative. For example, it won't follow the use through a phi node, and certainly won't allow it in a function call - even if the function is nocapture, it could make comparisons with the pointer.
David pointed out that I should probably break this out into a separate function though, so I'll do that.
================
Comment at: lib/Analysis/InstructionSimplify.cpp:2168
@@ +2167,3 @@
+ } else if (isa<IntrinsicInst>(I)) {
+ // Intrinsics should be safe (other calls would escape the pointer).
+ continue;
----------------
sanjoy wrote:
> `patchpoint`, `stackmap` and `gc.statepoint` all can escape values -- they're basically a call to an unknown function (I don't know if they'll show up as an `IntrinsicInst` though).
Thanks. David also pointed out he had some intrinsic that would escape a pointer. I'll build a whitelist here.
http://reviews.llvm.org/D13358
More information about the llvm-commits
mailing list