]> granicus.if.org Git - llvm/commitdiff
[SelectionDAG] Do minnum->minimum at legalization time instead of building time
authorBenjamin Kramer <benny.kra@googlemail.com>
Mon, 1 Jul 2019 11:00:23 +0000 (11:00 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Mon, 1 Jul 2019 11:00:23 +0000 (11:00 +0000)
The SDAGBuilder behavior stems from the days when we didn't have fast
math flags available in SDAG. We do now and doing the transformation in
the legalizer has the advantage that it also works for vector types.

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

lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/CodeGen/SelectionDAG/TargetLowering.cpp
test/CodeGen/WebAssembly/f32.ll
test/CodeGen/WebAssembly/simd-arith.ll

index 8a04d6244bd03f9d056f7d828ad0bba02381aaff..cdea8488ccbfed7ade44033f63762d1ee363af83 100644 (file)
@@ -6016,28 +6016,18 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
                              getValue(I.getArgOperand(0))));
     return;
   }
-  case Intrinsic::minnum: {
-    auto VT = getValue(I.getArgOperand(0)).getValueType();
-    unsigned Opc =
-        I.hasNoNaNs() && TLI.isOperationLegalOrCustom(ISD::FMINIMUM, VT)
-            ? ISD::FMINIMUM
-            : ISD::FMINNUM;
-    setValue(&I, DAG.getNode(Opc, sdl, VT,
+  case Intrinsic::minnum:
+    setValue(&I, DAG.getNode(ISD::FMINNUM, sdl,
+                             getValue(I.getArgOperand(0)).getValueType(),
                              getValue(I.getArgOperand(0)),
                              getValue(I.getArgOperand(1))));
     return;
-  }
-  case Intrinsic::maxnum: {
-    auto VT = getValue(I.getArgOperand(0)).getValueType();
-    unsigned Opc =
-        I.hasNoNaNs() && TLI.isOperationLegalOrCustom(ISD::FMAXIMUM, VT)
-            ? ISD::FMAXIMUM
-            : ISD::FMAXNUM;
-    setValue(&I, DAG.getNode(Opc, sdl, VT,
+  case Intrinsic::maxnum:
+    setValue(&I, DAG.getNode(ISD::FMAXNUM, sdl,
+                             getValue(I.getArgOperand(0)).getValueType(),
                              getValue(I.getArgOperand(0)),
                              getValue(I.getArgOperand(1))));
     return;
-  }
   case Intrinsic::minimum:
     setValue(&I, DAG.getNode(ISD::FMINIMUM, sdl,
                              getValue(I.getArgOperand(0)).getValueType(),
index 33050621348b4827e49d20e0d3e15e722f06a39f..772ffca1e5007c33d20a969ae7694b723c72931a 100644 (file)
@@ -5098,6 +5098,17 @@ SDValue TargetLowering::expandFMINNUM_FMAXNUM(SDNode *Node,
     return DAG.getNode(NewOp, dl, VT, Quiet0, Quiet1, Node->getFlags());
   }
 
+  // If the target has FMINIMUM/FMAXIMUM but not FMINNUM/FMAXNUM use that
+  // instead if there are no NaNs.
+  if (Node->getFlags().hasNoNaNs()) {
+    unsigned IEEE2018Op =
+        Node->getOpcode() == ISD::FMINNUM ? ISD::FMINIMUM : ISD::FMAXIMUM;
+    if (isOperationLegalOrCustom(IEEE2018Op, VT)) {
+      return DAG.getNode(IEEE2018Op, dl, VT, Node->getOperand(0),
+                         Node->getOperand(1), Node->getFlags());
+    }
+  }
+
   return SDValue();
 }
 
index 5208335b2781faa8f994032857e1f4865bd72bf8..7f74ddde82eefffc9da4c00cf53f7871c6fa7ec7 100644 (file)
@@ -149,6 +149,15 @@ define float @fmin32_intrinsic(float %x, float %y) {
   ret float %a
 }
 
+; CHECK-LABEL: fminnum32_intrinsic:
+; CHECK: f32.min $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
+; CHECK-NEXT: return $pop0{{$}}
+declare float @llvm.minnum.f32(float, float)
+define float @fminnum32_intrinsic(float %x, float %y) {
+  %a = call nnan float @llvm.minnum.f32(float %x, float %y)
+  ret float %a
+}
+
 ; CHECK-LABEL: fmax32_intrinsic:
 ; CHECK: f32.max $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
 ; CHECK-NEXT: return $pop0{{$}}
@@ -158,6 +167,15 @@ define float @fmax32_intrinsic(float %x, float %y) {
   ret float %a
 }
 
+; CHECK-LABEL: fmaxnum32_intrinsic:
+; CHECK: f32.max $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
+; CHECK-NEXT: return $pop0{{$}}
+declare float @llvm.maxnum.f32(float, float)
+define float @fmaxnum32_intrinsic(float %x, float %y) {
+  %a = call nnan float @llvm.maxnum.f32(float %x, float %y)
+  ret float %a
+}
+
 ; CHECK-LABEL: fma32:
 ; CHECK: {{^}} f32.call $push[[LR:[0-9]+]]=, fmaf, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
 ; CHECK-NEXT: return $pop[[LR]]{{$}}
index bd5479a0f35b569329398994e9a685dfb74b3220..410b2e6f5ab9d28e58817a199833423c29d0fae3 100644 (file)
@@ -1073,6 +1073,17 @@ define <4 x float> @min_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
   ret <4 x float> %a
 }
 
+; CHECK-LABEL: minnum_intrinsic_v4f32:
+; NO-SIMD128-NOT: f32x4
+; SIMD128-NEXT: .functype minnum_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
+; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <4 x float> @llvm.minnum.v4f32(<4 x float>, <4 x float>)
+define <4 x float> @minnum_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
+  %a = call nnan <4 x float> @llvm.minnum.v4f32(<4 x float> %x, <4 x float> %y)
+  ret <4 x float> %a
+}
+
 ; CHECK-LABEL: max_intrinsic_v4f32:
 ; NO-SIMD128-NOT: f32x4
 ; SIMD128-NEXT: .functype max_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
@@ -1084,6 +1095,17 @@ define <4 x float> @max_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
   ret <4 x float> %a
 }
 
+; CHECK-LABEL: maxnum_intrinsic_v4f32:
+; NO-SIMD128-NOT: f32x4
+; SIMD128-NEXT: .functype maxnum_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
+; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>)
+define <4 x float> @maxnum_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
+  %a = call nnan <4 x float> @llvm.maxnum.v4f32(<4 x float> %x, <4 x float> %y)
+  ret <4 x float> %a
+}
+
 ; CHECK-LABEL: min_const_intrinsic_v4f32:
 ; NO-SIMD128-NOT: f32x4
 ; SIMD128-NEXT: .functype min_const_intrinsic_v4f32 () -> (v128){{$}}