[PATCH] D48158: [SCEV] Simplify zext/trunc idiom that appears when handling bitmasks.
Justin Lebar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 13 20:32:50 PDT 2018
jlebar created this revision.
jlebar added a reviewer: sanjoy.
Herald added a subscriber: hiraditya.
Specifically, we transform
zext(2^K * (trunc X to iN)) to iM ->
2^K * (zext(trunc X to i{N-K}) to iM)<nuw>
This is helpful because pulling the 2^K out of the zext allows further
optimizations.
https://reviews.llvm.org/D48158
Files:
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll
llvm/test/Analysis/ScalarEvolution/and-xor.ll
Index: llvm/test/Analysis/ScalarEvolution/and-xor.ll
===================================================================
--- llvm/test/Analysis/ScalarEvolution/and-xor.ll
+++ llvm/test/Analysis/ScalarEvolution/and-xor.ll
@@ -25,3 +25,17 @@
%z = xor i64 %t, 8
ret i64 %z
}
+
+; Check that we transform the naive lowering of the sequence below,
+; (4 * (zext i5 (2 * (trunc i32 %x to i5)) to i32)),
+; to
+; (8 * (zext i4 (trunc i32 %x to i4) to i32))
+;
+; CHECK-LABEL: @test3
+define i32 @test3(i32 %x) {
+ %a = mul i32 %x, 8
+; CHECK: %b
+; CHECK-NEXT: --> (8 * (zext i4 (trunc i32 %x to i4) to i32))
+ %b = and i32 %a, 124
+ ret i32 %b
+}
Index: llvm/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll
===================================================================
--- llvm/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll
+++ llvm/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll
@@ -122,16 +122,16 @@
; LAA: Memory dependences are safe{{$}}
; LAA: SCEV assumptions:
; LAA-NEXT: {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> Added Flags: <nusw>
-; LAA-NEXT: {((2 * (zext i32 (2 * (trunc i64 %N to i32)) to i64))<nuw> + %a),+,-4}<%for.body> Added Flags: <nusw>
+; LAA-NEXT: {((4 * (zext i31 (trunc i64 %N to i31) to i64)) + %a),+,-4}<%for.body> Added Flags: <nusw>
; The expression for %mul_ext as analyzed by SCEV is
; (zext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64)
; We have added the nusw flag to turn this expression into the following SCEV:
; i64 {zext i32 (2 * (trunc i64 %N to i32)) to i64,+,-2}<%for.body>
; LAA: [PSE] %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext:
; LAA-NEXT: ((2 * (zext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64))<nuw> + %a)
-; LAA-NEXT: --> {((2 * (zext i32 (2 * (trunc i64 %N to i32)) to i64))<nuw> + %a),+,-4}<%for.body>
+; LAA-NEXT: --> {((4 * (zext i31 (trunc i64 %N to i31) to i64)) + %a),+,-4}<%for.body>
; LV-LABEL: f2
; LV-LABEL: for.body.lver.check
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -1778,6 +1778,33 @@
Ops.push_back(getZeroExtendExpr(Op, Ty, Depth + 1));
return getMulExpr(Ops, SCEV::FlagNUW, Depth + 1);
}
+
+ // zext(2^K * (trunc X to iN)) to iM ->
+ // 2^K * (zext(trunc X to i{N-K}) to iM)<nuw>
+ //
+ // Proof:
+ //
+ // zext(2^K * (trunc X to iN)) to iM
+ // = zext((trunc X to iN) << K) to iM
+ // = zext((trunc X to i{N-K}) << K)<nuw> to iM
+ // (because shl removes the top K bits)
+ // = zext((2^K * (trunc X to i{N-K}))<nuw>) to iM
+ // = (2^K * (zext(trunc X to i{N-K}) to iM))<nuw>.
+ //
+ if (SA->getNumOperands() == 2)
+ if (auto *MulLHS = dyn_cast<SCEVConstant>(SA->getOperand(0)))
+ if (MulLHS->getAPInt().isPowerOf2())
+ if (auto *TruncRHS = dyn_cast<SCEVTruncateExpr>(SA->getOperand(1))) {
+ int NewTruncBits = getTypeSizeInBits(TruncRHS->getType()) -
+ MulLHS->getAPInt().logBase2();
+ Type *TruncTy = IntegerType::get(getContext(), NewTruncBits);
+ assert(NewTruncBits > 0 && "Can't represent 2^N in 2^(N-1) bits.");
+ return getMulExpr(
+ getZeroExtendExpr(MulLHS, Ty),
+ getZeroExtendExpr(
+ getTruncateExpr(TruncRHS->getOperand(), TruncTy), Ty),
+ SCEV::FlagNUW, Depth + 1);
+ }
}
// The cast wasn't folded; create an explicit cast node.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48158.151300.patch
Type: text/x-patch
Size: 3649 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180614/4206166a/attachment.bin>
More information about the llvm-commits
mailing list