From 47e6904fe1bba337709bfa57fc3d57376bb27cb8 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 5 Sep 2016 23:38:22 +0000 Subject: [PATCH] [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: git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280677 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineCompares.cpp | 13 ++- test/Transforms/InstCombine/icmp-div-constant.ll | 93 ++++++++++++++++++++++ 2 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 test/Transforms/InstCombine/icmp-div-constant.ll diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index ad2bd1841f1..fc90c4a40a8 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1976,13 +1976,12 @@ Instruction *InstCombiner::foldICmpDivConstant(ICmpInst &Cmp, 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(Cmp.getOperand(1)); diff --git a/test/Transforms/InstCombine/icmp-div-constant.ll b/test/Transforms/InstCombine/icmp-div-constant.ll new file mode 100644 index 00000000000..98900ef8113 --- /dev/null +++ b/test/Transforms/InstCombine/icmp-div-constant.ll @@ -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 +} + -- 2.11.0