[PATCH] D41233: [InstCombine] Canonizing 'and' before 'shl'

Omer Paparo Bivas via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 19 06:53:57 PST 2017


opaparo added inline comments.


================
Comment at: test/Transforms/InstCombine/cast.ll:814
 ; CHECK-LABEL: @test59(
-; CHECK-NEXT:    [[C:%.*]] = zext i8 %A to i64
-; CHECK-NEXT:    [[D:%.*]] = shl nuw nsw i64 [[C]], 4
----------------
craig.topper wrote:
> Any idea why were weren't simplifying this before this change?
I've looked into it.
The key here is the first three instructions. Consider the old version:
  %C = zext i8 %A to i32
  %D = shl i32 %C, 4
  %E = and i32 %D, 48

vs the new version:
  %C = zext i8 %A to i32
  %E = and i32 %C, 3
  %D = shl i32 %E, 4

In the old version, 'shl' of 'zext' could not be transformed into 'zext' of 'shl' as in the general case they are not identical due to bits 8 and above of the result of the 'shl' that will be zeroed out. On the other hand, in the new version 'and' of 'zext' could be transformed to 'zext' of 'and'. Afterwards, since bits 8 and above of the 'shl' result are promised to be zeroes, 'shl' of 'zext' can now be transformed into 'zext' of 'shl'. This caused a chain reaction in which the 'zext' kept "sinking" down, eventually merging with the other 'zext'.
Note that, in the new version, if the RHS operand of the 'and' was greater or equal to 16 this transformation would again not be possible as there would again be a chance of losing bits. 'and' of 'zext' will still be transformed into 'zext' of 'and', but it will stop there.


Repository:
  rL LLVM

https://reviews.llvm.org/D41233





More information about the llvm-commits mailing list