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

Sanjoy Das sanjoy at playingwithpointers.com
Thu Mar 26 23:39:18 PDT 2015

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

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.

> 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"?

-- Sanjoy

More information about the llvm-dev mailing list