[PATCH] D46760: [InstCombine] Enhance narrowUDivURem.
Bixia Zheng via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri May 11 10:46:31 PDT 2018
bixia updated this revision to Diff 146358.
bixia added a comment.
Add another test case.
Repository:
rL LLVM
https://reviews.llvm.org/D46760
Files:
lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
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,36 @@
ret <2 x i32> %udiv
}
+define i64 @udiv_urem_twouses_xform(i32 %a) {
+; CHECK-LABEL: @udiv_urem_twouses_xform(
+; 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 i64 @udiv_urem_twouses_not_xform(i32 %a) {
+; CHECK-LABEL: @udiv_urem_twouses_not_xform(
+; CHECK-NEXT: [[A_ZEXT:%.*]] = zext i32 {{%.*}} to i64
+; CHECK-NEXT: [[UDIV:%.*]] = udiv i64 [[A_ZEXT:%.*]], 33
+; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[A_ZEXT:%.*]], 2147483649
+; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[UDIV]], [[UREM]]
+; CHECK-NEXT: ret i64 [[ADD]]
+;
+ %za = zext i32 %a to i64
+ %udiv = udiv i64 %za, 33
+ %urem = urem i64 %za, 2147483649
+ %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: 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.146358.patch
Type: text/x-patch
Size: 3206 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180511/080374c9/attachment.bin>
More information about the llvm-commits
mailing list