[LLVMdev] `llvm.$op.with.overflow`, InstCombine and ScalarEvolution

Andrew Trick atrick at apple.com
Thu Mar 26 23:57:09 PDT 2015

> On Mar 26, 2015, at 11:39 PM, Sanjoy Das <sanjoy at playingwithpointers.com> wrote:
>> The intrinsics tightly couple the operation with the branch, preventing the optimizer from obscuring the relationship, thereby effectively guaranteeing good codegen. If the intrinsics are needed to expose mid-level optimizations, I’m not aware of it. I think mid-level optimization should generally work on the canonical compare-and-branch form.
> The places within opt (other than InstCombine) that special case the
> _with_overflow intrinsics are ConstantFolding, ValueTracking and GVN.
> Their extent of "special casing" is just pretending "extractvalue 0
> (smul_with_overflow A B)" is "A * B", and the like so I don't think
> we'll lose optimization potential by not transforming IR to use
> the _with_overflow intrinsics in -instcombine.

Sure. The point is, transforming to _with_overflow never exposes *more* optimization in these passes.

> The _with_overflow instrinsics are also matched and handled in some
> places within SelectionDAG, ISel and some TTIs.  I'm more worried
> about these as it is possible that missing out on the materializing
> _with_overflow may affect codegen quality.  But we can always fix this
> by moving the "introduce _with_overflow" phase to within CodegenPrep.

Yes. Completely agree.

>> An alternative that avoids cloning+expanding the intrinsic would be to allow SCEV to analyze the expression for the intrinsic’s value result, but avoid replacing the intrinsic with a materialized SCEV expression (we would have no way to replace the overflow result anyway).
> If I understand you correctly, I suspect this will be hard to do right
> because SCEV expressions will
> have to track state that they don't track currently (which Value* did
> this AddRecExpr come from?).  We'll also end up with weird uniqueing
> issues -- is "extractvalue 0
> (uadd.with.overflow(A, B))" the same SCEVAddExpr* as "A + B”?

This is what I do not want to do. I think that approach is totally infeasible. I was suggesting that SCEV ignores overflow (just like ValueTracking/GVN), and the SCEV client never rewrites the intrinsic via SCEVExpander. The _with_overflow value can be substituted but not the overflow bit. I haven’t thought that approach through.


> -- Sanjoy

More information about the llvm-dev mailing list