This is an archive of the discontinued LLVM Phabricator instance.

[BypassSlowDivision] Teach bypass slow division not to interfere with div by constant where constants have been constant hoisted, but not moved from their basic block
ClosedPublic

Authored by craig.topper on Aug 20 2018, 3:02 PM.

Details

Summary

DAGCombiner doesn't pay attention to whether constants are opaque before doing the div by constant optimization. So BypassSlowDivision shouldn't introduce control flow that would make DAGCombiner unable to see an opaque constant. This can occur when a div and rem of the same constant are used in the same basic block. it will be hoisted, but not leave the block.

Longer term we probably need to look into the X86 immediate cost model used by constant hoisting and maybe not mark div/rem immediates for hoisting at all.

This fixes the case from PR38649.

Diff Detail

Repository
rL LLVM

Event Timeline

craig.topper created this revision.Aug 20 2018, 3:02 PM
spatel added inline comments.Aug 20 2018, 3:19 PM
lib/Transforms/Utils/BypassSlowDivision.cpp
200–203 ↗(On Diff #161571)

Similar check - can we handle div opcodes here?
There's an IR version of peekThroughBitcast() in InstCombineInternal.h. Lift that to a higher header, so we can use it here too?

craig.topper added inline comments.Aug 20 2018, 3:24 PM
lib/Transforms/Utils/BypassSlowDivision.cpp
200–203 ↗(On Diff #161571)

This code is specifically looking for a code sequence that you might find in a hash function. I don't think we want to check for div here. And it wouldn't help with the problem since this is called on the inputs to the div/rem.

In my case, I need to know the bitcast is there because I need to check the parent so peekthroughbitcast isn't useful.

spatel added inline comments.Aug 20 2018, 4:22 PM
lib/Transforms/Utils/BypassSlowDivision.cpp
395–397 ↗(On Diff #161571)

Use dyn_cast to reduce code:

if (auto *BitCast = dyn_cast<BitCastInst>(Divisor))
  if (BitCast->getParent() == SlowDivOrRem->getParent() &&
      isa<ConstantInt>(BitCast->getOperand(0)))
    return None;

Use dyn_cast

spatel accepted this revision.Aug 21 2018, 4:43 AM

LGTM

This revision is now accepted and ready to land.Aug 21 2018, 4:43 AM
This revision was automatically updated to reflect the committed changes.