From c93f771c2f8ef8795609e70340b566829925f5b2 Mon Sep 17 00:00:00 2001 From: Sanjoy Das Date: Fri, 28 Aug 2015 19:09:31 +0000 Subject: [PATCH] [InstCombine] Fix PR24605. PR24605 is caused due to an incorrect insert point in instcombine's IR builder. When simplifying %t = add X Y ... %m = icmp ... %t the replacement for %t should be placed before %t, not before %m, as there could be a use of %t between %t and %m. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246315 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineCompares.cpp | 6 ++++++ lib/Transforms/InstCombine/InstCombineInternal.h | 5 +++++ test/Transforms/InstCombine/pr24605.ll | 15 +++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 test/Transforms/InstCombine/pr24605.ll diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 905f66a380f..6e4336ef875 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2140,6 +2140,12 @@ bool InstCombiner::OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, return true; }; + // If the overflow check was an add followed by a compare, the insertion point + // may be pointing to the compare. We want to insert the new instructions + // before the add in case there are uses of the add between the add and the + // compare. + Builder->SetInsertPoint(&OrigI); + switch (OCF) { case OCF_INVALID: llvm_unreachable("bad overflow check kind!"); diff --git a/lib/Transforms/InstCombine/InstCombineInternal.h b/lib/Transforms/InstCombine/InstCombineInternal.h index ac934f1bd85..9f5cdcbb329 100644 --- a/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/lib/Transforms/InstCombine/InstCombineInternal.h @@ -360,6 +360,11 @@ private: /// \brief Try to optimize a sequence of instructions checking if an operation /// on LHS and RHS overflows. /// + /// If this overflow check is done via one of the overflow check intrinsics, + /// then CtxI has to be the call instruction calling that intrinsic. If this + /// overflow check is done by arithmetic followed by a compare, then CtxI has + /// to be the arithmetic instruction. + /// /// If a simplification is possible, stores the simplified result of the /// operation in OperationResult and result of the overflow check in /// OverflowResult, and return true. If no simplification is possible, diff --git a/test/Transforms/InstCombine/pr24605.ll b/test/Transforms/InstCombine/pr24605.ll new file mode 100644 index 00000000000..4b7b36137e6 --- /dev/null +++ b/test/Transforms/InstCombine/pr24605.ll @@ -0,0 +1,15 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i1 @f(i8* %a, i8 %b) { +; CHECK-LABEL: @f( +entry: + %or = or i8 %b, -117 + %sub = add i8 %or, -1 + store i8 %sub, i8* %a, align 1 + %cmp = icmp ugt i8 %or, %sub + ret i1 %cmp +; CHECK: ret i1 true +} -- 2.34.1