[llvm-dev] Hoisting a guarded division instruction causes division-by-zero

Alexey Zhikhartsev via llvm-dev llvm-dev at lists.llvm.org
Tue Dec 4 14:00:25 PST 2018


For our out-of-tree backend, Machine LICM hoists the division instruction
out of the following loop:



int foo(int n, int dividend, int divisor) {

  int a = 0;

  while (n--) {

    if (divisor != 0) {

      a += dividend / divisor;

    }

  }

  return a;

}



However, the division instruction causes a hardware exception when the
divisor is zero, so there's a discrepancy between the actual and expected
behaviours.



The most straightforward solution that declares the division instruction
with hasSideEffects=1 has a significant downside: unnecessary order edges
between division instructions and any other instructions that have
unmodelled side effects; these edges hinder instruction scheduling.
Although, I see that the X86 division instruction has unmodelled
side-effects, it is not surprising, since instruction scheduling is not
that important for out-of-order processors.



Another solution is to introduce a new flag to MachineInstr, e.g., isDiv
(similar to isAdd or mayLoad). Then, the MachineLICM pass will have to
check for this flag when it looks for loop invariants. Are there
significant downsides to this, or is there a better solution? I would
appreciate your thoughts.



Unfortunately, I cannot provide assembly code for our out-of-tree target,
for which I apologize. I tried to reproduce the problem for the PowerPC
backend: the division is hoisted but it seems that Power division
instruction (divw) does not trap, so there is no problem there (but my
knowledge of PPC is very limited).



Best,

Alex
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20181204/35cddaaf/attachment.html>


More information about the llvm-dev mailing list