[PATCH] D21493: [ValueTracking] Teach computeKnownBits for PHI nodes to compute sign bit for a recurrence with a NSW addition.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 18 13:26:39 PDT 2016


craig.topper created this revision.
craig.topper added reviewers: chandlerc, sanjoy, majnemer.
craig.topper added a subscriber: llvm-commits.

If a operation for a recurrence is an addition with no signed wrap and both input sign bits are 0, then the result sign bit must also be 0. Similar for the negative case.

I found this deficiency while playing around with a loop in the x86 backend that contained a signed division that could be optimized into an unsigned division if we could prove both inputs were positive. One of them being the loop induction variable. With this patch we can perform the conversion for this case. The test case here is a contrived variation of the loop I was looking at.

http://reviews.llvm.org/D21493

Files:
  lib/Analysis/ValueTracking.cpp
  test/Transforms/BBVectorize/loop1.ll
  test/Transforms/InstCombine/phi.ll

Index: test/Transforms/InstCombine/phi.ll
===================================================================
--- test/Transforms/InstCombine/phi.ll
+++ test/Transforms/InstCombine/phi.ll
@@ -879,3 +879,35 @@
   %cmp1 = icmp ne i32 %a.0, 0
   ret i1  %cmp1
 }
+
+; This test makes sure we can determine that the inputs to the sdiv in the loop
+; are non-negative and can become a udiv. This requires that we recognize that
+; the loop induction can never have its sign bit set.
+;
+; CHECK-LABEL: @phi_nsw_induction_sdiv_udiv
+; CHECK: udiv
+; CHECK: udiv
+define i32 @phi_nsw_induction_sdiv_udiv(i32 %NumElts, i32 %ScalarSize) {
+entry:
+  %div = udiv i32 128, %ScalarSize
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %Sum.0 = phi i32 [ 0, %entry ], [ %add, %for.inc ]
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %cmp = icmp ne i32 %i.0, %NumElts
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  ; this should become a udiv
+  %div1 = sdiv i32 %i.0, %div
+  %add = add nsw i32 %Sum.0, %div1
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret i32 %Sum.0
+}
Index: test/Transforms/BBVectorize/loop1.ll
===================================================================
--- test/Transforms/BBVectorize/loop1.ll
+++ test/Transforms/BBVectorize/loop1.ll
@@ -83,7 +83,7 @@
 ; CHECK-UNRL: %add12 = fadd <2 x double> %add7, %mul11
 ; CHECK-UNRL: %4 = bitcast double* %arrayidx14 to <2 x double>*
 ; CHECK-UNRL: store <2 x double> %add12, <2 x double>* %4, align 8
-; CHECK-UNRL: %indvars.iv.next.1 = add nsw i64 %indvars.iv, 2
+; CHECK-UNRL: %indvars.iv.next.1 = add nuw nsw i64 %indvars.iv, 2
 ; CHECK-UNRL: %lftr.wideiv.1 = trunc i64 %indvars.iv.next.1 to i32
 ; CHECK-UNRL: %exitcond.1 = icmp eq i32 %lftr.wideiv.1, 10
 ; CHECK-UNRL: br i1 %exitcond.1, label %for.end, label %for.body
Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -1240,6 +1240,18 @@
           KnownZero = APInt::getLowBitsSet(BitWidth,
                                            std::min(KnownZero2.countTrailingOnes(),
                                                     KnownZero3.countTrailingOnes()));
+
+          // If the operation is an addition that can't have signed overflow,
+          // then the sign bit is known to be zero if both input sign bits
+          // are zero. Similar for two negative inputs.
+          if (Opcode == Instruction::Add &&
+              cast<OverflowingBinaryOperator>(LU)->hasNoSignedWrap()) {
+            if (KnownZero2.isNegative() && KnownZero3.isNegative())
+              KnownZero.setBit(BitWidth-1);
+            if (KnownOne2.isNegative() && KnownOne3.isNegative())
+              KnownOne.setBit(BitWidth-1);
+          }
+
           break;
         }
       }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21493.61171.patch
Type: text/x-patch
Size: 3137 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160618/ce08c40f/attachment.bin>


More information about the llvm-commits mailing list