[PATCH] D46760: [InstCombine] Enhance narrowUDivURem.
Bixia Zheng via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri May 11 10:13:26 PDT 2018
bixia created this revision.
Herald added subscribers: llvm-commits, jlebar, sanjoy.
Transform udiv/urem (zext X), C to zext (udiv/urem X, C') when X has two uses
and both uses can be transformed. This is a common pattern seen in code
generated by the XLA GPU backend.
Add a test case.
Repository:
rL LLVM
https://reviews.llvm.org/D46760
Files:
lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
test/Transforms/InstCombine/narrow.ll
test/Transforms/InstCombine/udivrem-change-width.ll
Index: test/Transforms/InstCombine/udivrem-change-width.ll
===================================================================
--- test/Transforms/InstCombine/udivrem-change-width.ll
+++ test/Transforms/InstCombine/udivrem-change-width.ll
@@ -75,6 +75,21 @@
ret <2 x i32> %udiv
}
+define i64 @udiv_urem_twouses(i32 %a) {
+; CHECK-LABEL: @udiv_urem_twouses(
+; CHECK-NEXT: [[UDIV:%.*]] = udiv i32 [[A:%.*]], 33
+; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[A:%.*]], 33
+; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[UDIV]], [[UREM]]
+; CHECK-NEXT: [[ADD_ZEXT:%.*]] = zext i32 [[ADD:%.*]] to i64
+; CHECK-NEXT: ret i64 [[ADD_ZEXT]]
+;
+ %za = zext i32 %a to i64
+ %udiv = udiv i64 %za, 33
+ %urem = urem i64 %za, 33
+ %uadd = add i64 %udiv, %urem
+ ret i64 %uadd
+}
+
define i32 @udiv_i32_multiuse(i8 %a, i8 %b) {
; CHECK-LABEL: @udiv_i32_multiuse(
; CHECK-NEXT: [[ZA:%.*]] = zext i8 %a to i32
Index: test/Transforms/InstCombine/narrow.ll
===================================================================
--- test/Transforms/InstCombine/narrow.ll
+++ test/Transforms/InstCombine/narrow.ll
@@ -236,4 +236,3 @@
%logic = xor i32 %zext, %phi
ret i32 %logic
}
-
Index: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -918,8 +918,34 @@
}
Constant *C;
- if ((match(N, m_OneUse(m_ZExt(m_Value(X)))) && match(D, m_Constant(C))) ||
- (match(D, m_OneUse(m_ZExt(m_Value(X)))) && match(N, m_Constant(C)))) {
+ bool CanConvert = false;
+ if ((match(N, m_ZExt(m_Value(X))) && match(D, m_Constant(C)))) {
+ if (N->hasOneUse()) {
+ CanConvert = true;
+ } else if (N->hasNUses(2)) {
+ // Handle the case with two uses to support this common pattern:
+ // warp_id = N UDIV 32
+ // lane_id = N UREM 32
+ Value::user_iterator UI = N->user_begin();
+ llvm::Instruction *I1 =
+ dyn_cast<llvm::Instruction>(*UI);
+ llvm::Instruction *I2 =
+ dyn_cast<llvm::Instruction>(*(++UI));
+ I2 = (I1 == &I) ? I2 : I1;
+ // Instead of allowing a second constant C2 that meets the requirement of
+ // ConstantExpr::getZExt(Trunc(C2), Ty) == C2, we simply require the
+ // constant to be the same as the first constant.
+ if (I2 && (match(I2, m_UDiv(m_Specific(N), m_Specific(C))) ||
+ match(I2, m_URem(m_Specific(N), m_Specific(C))))) {
+ CanConvert = true;
+ }
+ }
+ } else if (match(D, m_OneUse(m_ZExt(m_Value(X)))) &&
+ match(N, m_Constant(C))) {
+ CanConvert = true;
+ }
+
+ if (CanConvert) {
// If the constant is the same in the smaller type, use the narrow version.
Constant *TruncC = ConstantExpr::getTrunc(C, X->getType());
if (ConstantExpr::getZExt(TruncC, Ty) != C)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46760.146346.patch
Type: text/x-patch
Size: 2931 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180511/53c1864b/attachment.bin>
More information about the llvm-commits
mailing list