[PATCH] D63036: [RFC] LLVM IR constant expressions never trap.

Eli Friedman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 7 17:31:29 PDT 2019


efriedma created this revision.
efriedma added reviewers: hfinkel, chandlerc, jdoerfert, aemerson.
Herald added a project: LLVM.

Currently, constants have a property "Constant::canTrap", which is whether they contain a division that might have undefined behavior. If an instruction has a canTrap constant expression as an operand, and that constant expression contains a division with undefined behavior, the instruction has undefined behavior.  For PHI nodes, the behavior is only undefined along the corresponding edges.  This isn't documented anywhere in LangRef, but we use it to avoid certain transforms in a few optimization passes. For example, isSafeToSpeculativelyExecute checks whether instructions have a canTrap operand.

In practice, canTrap is almost never true: the only way create such an expression is to do something strange with the address of a global, so the denominator of a division is a complex constant expression.  This means we have a lot of complexity with very little test coverage.  So it would be nice if we could simplify the rules here.

This patch proposes to give up on the whole "canTrap" thing, and redefine the meaning of division in constant expressions.  With this patch, if a constant expression divides by zero, or contains an overflowing divide, the result is poison.   This simplifies a bunch of code.  It also fixes an infinite loop bug involving a canTrap constant, a PHI, and an unsplittable critical edge. The downside is a slight performance hit: if we do end up with a divide constant expression with a complex denominator, we generate extra code to avoid the trap.

There are a few ways to reduce the performance hit that I haven't tried to implement.  On architectures where division never traps, we could avoid generating extra code.  We could also try to avoid constant-folding divide instructions that would result in a complex constant expression.

TODO: I haven't fixed ConstantExpr::getAsInstruction.  (I don't think any of the in-tree users are actually affected by this, but it could have out-of-tree effects.)


Repository:
  rL LLVM

https://reviews.llvm.org/D63036

Files:
  docs/LangRef.rst
  include/llvm/Analysis/ValueTracking.h
  include/llvm/CodeGen/GlobalISel/IRTranslator.h
  include/llvm/IR/Constant.h
  lib/Analysis/CodeMetrics.cpp
  lib/Analysis/ValueTracking.cpp
  lib/CodeGen/SelectionDAG/FastISel.cpp
  lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
  lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
  lib/IR/Constants.cpp
  lib/Transforms/Utils/SimplifyCFG.cpp
  lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
  test/CodeGen/X86/critical-edge-split-2.ll
  test/CodeGen/X86/divide-constant.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63036.203646.patch
Type: text/x-patch
Size: 33266 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190608/e7dcb613/attachment.bin>


More information about the llvm-commits mailing list