Don't create a MIN/MAX node if the underlying compare has more than one use.
authorJames Molloy <james.molloy@arm.com>
Thu, 4 Jun 2015 13:48:23 +0000 (13:48 +0000)
committerJames Molloy <james.molloy@arm.com>
Thu, 4 Jun 2015 13:48:23 +0000 (13:48 +0000)
If the compare in a select pattern has another use then it can't be removed, so we'd just
be creating repeated code if we created a min/max node.

Spotted by Matt Arsenault!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239037 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
test/CodeGen/AArch64/minmax.ll

index 9a81ec51ddad4a71ab4a959c24c9fd3e51f9707b..6b366cc4af6fda26a43d36ca96bde3cbcbaf24d1 100644 (file)
@@ -2282,7 +2282,11 @@ void SelectionDAGBuilder::visitSelect(const User &I) {
     while (TLI.getTypeAction(Ctx, VT) == TargetLoweringBase::TypeSplitVector)
       VT = TLI.getTypeToTransformTo(Ctx, VT);
 
-    if (Opc != ISD::DELETED_NODE && TLI.isOperationLegalOrCustom(Opc, VT)) {
+    if (Opc != ISD::DELETED_NODE && TLI.isOperationLegalOrCustom(Opc, VT) &&
+        // If the underlying comparison instruction is used by any other instruction,
+        // the consumed instructions won't be destroyed, so it is not profitable
+        // to convert to a min/max.
+        cast<SelectInst>(&I)->getCondition()->hasOneUse()) {
       OpCode = Opc;
       LHSVal = getValue(LHS);
       RHSVal = getValue(RHS);
index a6b5adebe107a0c2500f8ef238926263bea047fc..df4912ca1f7ab1b2c9a6f8ec84e3b572933483fb 100644 (file)
@@ -94,3 +94,14 @@ define <16 x i32> @t11(<16 x i32> %a, <16 x i32> %b) {
   %t2 = select <16 x i1> %t1, <16 x i32> %a, <16 x i32> %b
   ret <16 x i32> %t2
 }
+
+; CHECK-LABEL: t12
+; CHECK-NOT: umin
+; The icmp is used by two instructions, so don't produce a umin node.
+define <16 x i8> @t12(<16 x i8> %a, <16 x i8> %b) {
+  %t1 = icmp ugt <16 x i8> %b, %a
+  %t2 = select <16 x i1> %t1, <16 x i8> %a, <16 x i8> %b
+  %t3 = zext <16 x i1> %t1 to <16 x i8>
+  %t4 = add <16 x i8> %t3, %t2
+  ret <16 x i8> %t4
+}