Defer some shl transforms to DAGCombine.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 19 Apr 2012 16:46:26 +0000 (16:46 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 19 Apr 2012 16:46:26 +0000 (16:46 +0000)
commit0d5fcae6cd7b96a5a483d6179d2908517970169c
tree91dbfb1fe1fc44579921c52f22b9580ad7b5cf6c
parent057a4b40a65692ea54e0a00cb6ea27d0855be51f
Defer some shl transforms to DAGCombine.

The shl instruction is used to represent multiplication by a constant
power of two as well as bitwise left shifts. Some InstCombine
transformations would turn an shl instruction into a bit mask operation,
making it difficult for later analysis passes to recognize the
constsnt multiplication.

Disable those shl transformations, deferring them to DAGCombine time.
An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'.

These transformations are deferred:

  (X >>? C) << C   --> X & (-1 << C)  (When X >> C has multiple uses)
  (X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2)   (When C2 > C1)
  (X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2)  (When C1 > C2)

The corresponding exact transformations are preserved, just like
div-exact + mul:

  (X >>?,exact C) << C   --> X
  (X >>?,exact C1) << C2 --> X << (C2-C1)
  (X >>?,exact C1) << C2 --> X >>?,exact (C1-C2)

The disabled transformations could also prevent the instruction selector
from recognizing rotate patterns in hash functions and cryptographic
primitives. I have a test case for that, but it is too fragile.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155136 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Transforms/InstCombine/InstCombineShifts.cpp
test/Transforms/InstCombine/2010-11-01-lshr-mask.ll
test/Transforms/InstCombine/apint-shift.ll
test/Transforms/InstCombine/cast.ll
test/Transforms/InstCombine/shift.ll
test/Transforms/PhaseOrdering/basic.ll
test/Transforms/PhaseOrdering/scev.ll [new file with mode: 0644]