[llvm] r280677 - [InstCombine] don't assert that division-by-constant has been folded (PR30281)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 5 16:38:22 PDT 2016


Author: spatel
Date: Mon Sep  5 18:38:22 2016
New Revision: 280677

URL: http://llvm.org/viewvc/llvm-project?rev=280677&view=rev
Log:
[InstCombine] don't assert that division-by-constant has been folded (PR30281)

This is effectively a revert of:
https://reviews.llvm.org/rL280115

And this should fix
https://llvm.org/bugs/show_bug.cgi?id=30281:


Added:
    llvm/trunk/test/Transforms/InstCombine/icmp-div-constant.ll
Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=280677&r1=280676&r2=280677&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Mon Sep  5 18:38:22 2016
@@ -1976,13 +1976,12 @@ Instruction *InstCombiner::foldICmpDivCo
   if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned())
     return nullptr;
 
-  // These constant divides should already be folded in InstSimplify.
-  assert(*C2 != 0 && "The ProdOV computation fails on divide by zero.");
-  assert(*C2 != 1 && "Funny cases with INT_MIN will fail.");
-
-  // This constant divide should already be folded in InstCombine.
-  assert(!(DivIsSigned && C2->isAllOnesValue()) &&
-         "The overflow computation will fail.");
+  // The ProdOV computation fails on divide by 0 and divide by -1. Cases with
+  // INT_MIN will also fail if the divisor is 1. Although folds of all these
+  // division-by-constant cases should be present, we can not assert that they
+  // have happened before we reach this icmp instruction.
+  if (*C2 == 0 || *C2 == 1 || (DivIsSigned && C2->isAllOnesValue()))
+    return nullptr;
 
   // TODO: We could do all of the computations below using APInt.
   Constant *CmpRHS = cast<Constant>(Cmp.getOperand(1));

Added: llvm/trunk/test/Transforms/InstCombine/icmp-div-constant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp-div-constant.ll?rev=280677&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/icmp-div-constant.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/icmp-div-constant.ll Mon Sep  5 18:38:22 2016
@@ -0,0 +1,93 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; PR30281 - https://llvm.org/bugs/show_bug.cgi?id=30281
+
+; All of these tests contain foldable division-by-constant instructions, but we
+; can't assert that those folds have occurred before we process the later icmp.
+
+define i32 @icmp_div(i16 %a, i16 %c) {
+; CHECK-LABEL: @icmp_div(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 %a, 0
+; CHECK-NEXT:    br i1 [[TOBOOL]], label %then, label %exit
+; CHECK:       then:
+; CHECK-NEXT:    [[NOT_CMP:%.*]] = icmp eq i16 %c, 0
+; CHECK-NEXT:    [[PHITMP1:%.*]] = sext i1 [[NOT_CMP]] to i32
+; CHECK-NEXT:    br label %exit
+; CHECK:       exit:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, %entry ], [ [[PHI:%.*]]tmp1, %then ]
+; CHECK-NEXT:    ret i32 [[PHI]]
+;
+entry:
+  %tobool = icmp eq i16 %a, 0
+  br i1 %tobool, label %then, label %exit
+
+then:
+  %div = sdiv i16 %c, -1
+  %cmp = icmp ne i16 %div, 0
+  br label %exit
+
+exit:
+  %phi = phi i1 [ false, %entry ], [ %cmp, %then ]
+  %zext = zext i1 %phi to i32
+  %add = add nsw i32 %zext, -1
+  ret i32 %add
+}
+
+define i32 @icmp_div2(i16 %a, i16 %c) {
+; CHECK-LABEL: @icmp_div2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 %a, 0
+; CHECK-NEXT:    br i1 [[TOBOOL]], label %then, label %exit
+; CHECK:       then:
+; CHECK-NEXT:    br label %exit
+; CHECK:       exit:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, %entry ], [ 0, %then ]
+; CHECK-NEXT:    ret i32 [[PHI]]
+;
+entry:
+  %tobool = icmp eq i16 %a, 0
+  br i1 %tobool, label %then, label %exit
+
+then:
+  %div = sdiv i16 %c, 0
+  %cmp = icmp ne i16 %div, 0
+  br label %exit
+
+exit:
+  %phi = phi i1 [ false, %entry ], [ %cmp, %then ]
+  %zext = zext i1 %phi to i32
+  %add = add nsw i32 %zext, -1
+  ret i32 %add
+}
+
+define i32 @icmp_div3(i16 %a, i16 %c) {
+; CHECK-LABEL: @icmp_div3(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 %a, 0
+; CHECK-NEXT:    br i1 [[TOBOOL]], label %then, label %exit
+; CHECK:       then:
+; CHECK-NEXT:    [[NOT_CMP:%.*]] = icmp eq i16 %c, 0
+; CHECK-NEXT:    [[PHITMP1:%.*]] = sext i1 [[NOT_CMP]] to i32
+; CHECK-NEXT:    br label %exit
+; CHECK:       exit:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, %entry ], [ [[PHI:%.*]]tmp1, %then ]
+; CHECK-NEXT:    ret i32 [[PHI]]
+;
+entry:
+  %tobool = icmp eq i16 %a, 0
+  br i1 %tobool, label %then, label %exit
+
+then:
+  %div = sdiv i16 %c, 1
+  %cmp = icmp ne i16 %div, 0
+  br label %exit
+
+exit:
+  %phi = phi i1 [ false, %entry ], [ %cmp, %then ]
+  %zext = zext i1 %phi to i32
+  %add = add nsw i32 %zext, -1
+  ret i32 %add
+}
+




More information about the llvm-commits mailing list