From a8231e7f59c2f43d11c387030e5e0c29670bd5a9 Mon Sep 17 00:00:00 2001 From: Sanjoy Das Date: Sat, 5 Dec 2015 23:44:22 +0000 Subject: [PATCH] [InstCombine] Call getCmpPredicateForMinMax only with a valid SPF Summary: There are `SelectPatternFlavor`s that don't represent min or max idioms, and we should not be passing those to `getCmpPredicateForMinMax`. Fixes PR25745. Reviewers: majnemer Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D15249 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254869 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/ValueTracking.h | 5 +++++ .../InstCombine/InstCombineSelect.cpp | 6 +++++- test/Transforms/InstCombine/pr25745.ll | 20 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 test/Transforms/InstCombine/pr25745.ll diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index b34d6bac1f3..eb2c000e07c 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -412,6 +412,11 @@ namespace llvm { bool Ordered; /// When implementing this min/max pattern as /// fcmp; select, does the fcmp have to be /// ordered? + + /// \brief Return true if \p SPF is a min or a max pattern. + static bool isMinOrMax(SelectPatternFlavor SPF) { + return !(SPF == SPF_UNKNOWN || SPF == SPF_ABS || SPF == SPF_NABS); + } }; /// Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind /// and providing the out parameter results if we successfully match. diff --git a/lib/Transforms/InstCombine/InstCombineSelect.cpp b/lib/Transforms/InstCombine/InstCombineSelect.cpp index 2baa131bc99..776704d1efa 100644 --- a/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -1070,7 +1070,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { SelectPatternResult SPR = matchSelectPattern(&SI, LHS, RHS, &CastOp); auto SPF = SPR.Flavor; - if (SPF) { + if (SelectPatternResult::isMinOrMax(SPF)) { // Canonicalize so that type casts are outside select patterns. if (LHS->getType()->getPrimitiveSizeInBits() != SI.getType()->getPrimitiveSizeInBits()) { @@ -1091,11 +1091,15 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { SI.getType()); return ReplaceInstUsesWith(SI, NewSI); } + } + if (SPF) { // MAX(MAX(a, b), a) -> MAX(a, b) // MIN(MIN(a, b), a) -> MIN(a, b) // MAX(MIN(a, b), a) -> a // MIN(MAX(a, b), a) -> a + // ABS(ABS(a)) -> ABS(a) + // NABS(NABS(a)) -> NABS(a) if (SelectPatternFlavor SPF2 = matchSelectPattern(LHS, LHS2, RHS2).Flavor) if (Instruction *R = FoldSPFofSPF(cast(LHS),SPF2,LHS2,RHS2, SI, SPF, RHS)) diff --git a/test/Transforms/InstCombine/pr25745.ll b/test/Transforms/InstCombine/pr25745.ll new file mode 100644 index 00000000000..3bf9efc92b9 --- /dev/null +++ b/test/Transforms/InstCombine/pr25745.ll @@ -0,0 +1,20 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +; Checking for a crash + +declare void @use.i1(i1 %val) +declare void @use.i64(i64 %val) + +define i64 @f(i32 %x) { +; CHECK-LABEL: @f( + entry: + %x.wide = sext i32 %x to i64 + %minus.x = sub i32 0, %x + %minus.x.wide = sext i32 %minus.x to i64 + %c = icmp slt i32 %x, 0 + %val = select i1 %c, i64 %x.wide, i64 %minus.x.wide + call void @use.i1(i1 %c) + call void @use.i64(i64 %x.wide) + ret i64 %val +; CHECK: ret i64 %val +} -- 2.34.1