From: Sanjay Patel Date: Thu, 16 Mar 2017 20:42:45 +0000 (+0000) Subject: [InstCombine] avoid breaking up bitcasted vector min/max patterns (PR32306) X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4616521acae6334c3c53d29eb7e02aa4c080ca8b;p=llvm [InstCombine] avoid breaking up bitcasted vector min/max patterns (PR32306) As the related tests show, we're not canonicalizing to this form for scalars or vectors yet, but this solves the immediate problem in: https://bugs.llvm.org/show_bug.cgi?id=32306 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297989 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineSelect.cpp b/lib/Transforms/InstCombine/InstCombineSelect.cpp index b8c1daab3f6..84dace5db76 100644 --- a/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -120,6 +120,16 @@ static Constant *getSelectFoldableConstant(Instruction *I) { /// We have (select c, TI, FI), and we know that TI and FI have the same opcode. Instruction *InstCombiner::foldSelectOpOp(SelectInst &SI, Instruction *TI, Instruction *FI) { + // Don't break up min/max patterns. The hasOneUse checks below prevent that + // for most cases, but vector min/max with bitcasts can be transformed. If the + // one-use restrictions are eased for other patterns, we still don't want to + // obfuscate min/max. + if ((match(&SI, m_SMin(m_Value(), m_Value())) || + match(&SI, m_SMax(m_Value(), m_Value())) || + match(&SI, m_UMin(m_Value(), m_Value())) || + match(&SI, m_UMax(m_Value(), m_Value())))) + return nullptr; + // If this is a cast from the same type, merge. if (TI->getNumOperands() == 1 && TI->isCast()) { Type *FIOpndTy = FI->getOperand(0)->getType(); diff --git a/test/Transforms/InstCombine/minmax-fold.ll b/test/Transforms/InstCombine/minmax-fold.ll index bdb6d09ae06..19a7341fdc2 100644 --- a/test/Transforms/InstCombine/minmax-fold.ll +++ b/test/Transforms/InstCombine/minmax-fold.ll @@ -529,15 +529,16 @@ define float @bitcast_scalar_umax(float %x, float %y) { } ; PR32306 - https://bugs.llvm.org/show_bug.cgi?id=32306 -; FIXME: The icmp/select form a canonical smin, so don't hide that by folding the final bitcast into the select. +; The icmp/select form a canonical smin, so don't hide that by folding the final bitcast into the select. define <8 x float> @bitcast_vector_smin(<8 x float> %x, <8 x float> %y) { ; CHECK-LABEL: @bitcast_vector_smin( ; CHECK-NEXT: [[BCX:%.*]] = bitcast <8 x float> %x to <8 x i32> ; CHECK-NEXT: [[BCY:%.*]] = bitcast <8 x float> %y to <8 x i32> ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <8 x i32> [[BCX]], [[BCY]] -; CHECK-NEXT: [[SEL_V:%.*]] = select <8 x i1> [[CMP]], <8 x float> %x, <8 x float> %y -; CHECK-NEXT: ret <8 x float> [[SEL_V]] +; CHECK-NEXT: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x i32> [[BCX]], <8 x i32> [[BCY]] +; CHECK-NEXT: [[BCS:%.*]] = bitcast <8 x i32> [[SEL]] to <8 x float> +; CHECK-NEXT: ret <8 x float> [[BCS]] ; %bcx = bitcast <8 x float> %x to <8 x i32> %bcy = bitcast <8 x float> %y to <8 x i32>