[llvm] [SelectionDAG] Remove `NoSignedZerosFPMath` in dag combiner (PR #180130)

via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 6 04:26:34 PST 2026


https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/180130

>From 1abc71513ef04c826bb914166c23c7e511c2ec28 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Fri, 6 Feb 2026 15:00:37 +0800
Subject: [PATCH] [SelectionDAG] Remove `NoSignedZerosFPMath` in dag combiner

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |   6 +-
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |   8 +
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  12 +
 llvm/test/CodeGen/AArch64/fp-to-int-to-fp.ll  | 359 +++++++++++-------
 llvm/test/CodeGen/AArch64/ftrunc.ll           |  11 +-
 llvm/test/CodeGen/AMDGPU/fp-to-int-to-fp.ll   |  61 +--
 .../CodeGen/PowerPC/fp-int128-fp-combine.ll   |   7 +-
 llvm/test/CodeGen/PowerPC/fp-to-int-to-fp.ll  |  10 +-
 llvm/test/CodeGen/PowerPC/ftrunc-vec.ll       |  11 +-
 .../CodeGen/PowerPC/no-extra-fp-conv-ldst.ll  |  14 +-
 llvm/test/CodeGen/X86/ftrunc.ll               |  28 +-
 11 files changed, 308 insertions(+), 219 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index df69f0870d27a..d2bf2d3b8e8ad 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -19310,7 +19310,8 @@ static SDValue foldFPToIntToFP(SDNode *N, const SDLoc &DL, SelectionDAG &DAG,
   // as example, it first becomes integer 0, and is converted back to +0.0.
   // FTRUNC on its own could produce -0.0.
 
-  // FIXME: We should be able to use node-level FMF here.
+  // FIXME: We should be able to use node-level FMF here, but currently it is
+  // impossible because nneg in uitofp is conflict with fast-math flags.
   EVT VT = N->getValueType(0);
   if (!TLI.isOperationLegal(ISD::FTRUNC, VT))
     return SDValue();
@@ -19319,8 +19320,7 @@ static SDValue foldFPToIntToFP(SDNode *N, const SDLoc &DL, SelectionDAG &DAG,
   bool IsSigned = N->getOpcode() == ISD::SINT_TO_FP;
   assert(IsSigned || IsUnsigned);
 
-  bool IsSignedZeroSafe = DAG.getTarget().Options.NoSignedZerosFPMath ||
-                          DAG.canIgnoreSignBitOfZero(SDValue(N, 0));
+  bool IsSignedZeroSafe = DAG.canIgnoreSignBitOfZero(SDValue(N, 0));
   // For signed conversions: The optimization changes signed zero behavior.
   if (IsSigned && !IsSignedZeroSafe)
     return SDValue();
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 302b8059e4df0..c0a44f39640fe 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6289,6 +6289,14 @@ bool SelectionDAG::canIgnoreSignBitOfZero(const SDUse &Use) const {
   case ISD::FP_TO_UINT:
     // fp-to-int conversions normalize signed zeros.
     return true;
+  case ISD::AssertNoFPClass: {
+    // nofpclass may filter out zeros.
+    if (const auto *MaskNode = dyn_cast<ConstantSDNode>(User->getOperand(1))) {
+      uint64_t Mask = MaskNode->getZExtValue();
+      return (Mask | fcZero) == fcZero;
+    }
+    return false;
+  }
   default:
     return false;
   }
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index e191cc5524a14..6b93959b921e6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2213,6 +2213,16 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
     return;
   }
 
+  auto buildRetOpAssertNoFPClass = [&](SDValue &RetOp) {
+    FPClassTest NoFPClass = FuncInfo.Fn->getAttributes().getRetNoFPClass();
+    if (NoFPClass != fcNone) {
+      SDValue SDNoFPClass = DAG.getTargetConstant(
+          static_cast<uint64_t>(NoFPClass), getCurSDLoc(), MVT::i32);
+      RetOp = DAG.getNode(ISD::AssertNoFPClass, getCurSDLoc(),
+                          RetOp.getValueType(), RetOp, SDNoFPClass);
+    }
+  };
+
   if (!FuncInfo.CanLowerReturn) {
     Register DemoteReg = FuncInfo.DemoteRegister;
 
@@ -2223,6 +2233,7 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
     SDValue RetPtr =
         DAG.getCopyFromReg(Chain, getCurSDLoc(), DemoteReg, PtrValueVT);
     SDValue RetOp = getValue(I.getOperand(0));
+    buildRetOpAssertNoFPClass(RetOp);
 
     SmallVector<EVT, 4> ValueVTs, MemVTs;
     SmallVector<uint64_t, 4> Offsets;
@@ -2256,6 +2267,7 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
     unsigned NumValues = Types.size();
     if (NumValues) {
       SDValue RetOp = getValue(I.getOperand(0));
+      buildRetOpAssertNoFPClass(RetOp);
 
       const Function *F = I.getParent()->getParent();
 
diff --git a/llvm/test/CodeGen/AArch64/fp-to-int-to-fp.ll b/llvm/test/CodeGen/AArch64/fp-to-int-to-fp.ll
index f7d9cefc357d8..534a8df28e2df 100644
--- a/llvm/test/CodeGen/AArch64/fp-to-int-to-fp.ll
+++ b/llvm/test/CodeGen/AArch64/fp-to-int-to-fp.ll
@@ -1,6 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=aarch64 < %s | FileCheck %s --check-prefixes=CHECK,SIGNED-ZEROS
-; RUN: llc -mtriple=aarch64 --enable-no-signed-zeros-fp-math < %s | FileCheck %s --check-prefixes=CHECK,NO-SIGNED-ZEROS
+; RUN: llc -mtriple=aarch64 < %s | FileCheck %s
 
 ; Test folding of float->int->float roundtrips into float-only operations.
 ; The optimization could converts patterns like:
@@ -9,16 +8,22 @@
 ; This is relevant for AArch64 as it avoids GPR bouncing and keeps computation in SIMD/FP registers.
 
 define float @test_signed_basic(float %x) {
-; SIGNED-ZEROS-LABEL: test_signed_basic:
-; SIGNED-ZEROS:       // %bb.0: // %entry
-; SIGNED-ZEROS-NEXT:    fcvtzs s0, s0
-; SIGNED-ZEROS-NEXT:    scvtf s0, s0
-; SIGNED-ZEROS-NEXT:    ret
-;
-; NO-SIGNED-ZEROS-LABEL: test_signed_basic:
-; NO-SIGNED-ZEROS:       // %bb.0: // %entry
-; NO-SIGNED-ZEROS-NEXT:    frintz s0, s0
-; NO-SIGNED-ZEROS-NEXT:    ret
+; CHECK-LABEL: test_signed_basic:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtzs s0, s0
+; CHECK-NEXT:    scvtf s0, s0
+; CHECK-NEXT:    ret
+entry:
+  %i = fptosi float %x to i32
+  %f = sitofp i32 %i to float
+  ret float %f
+}
+
+define nofpclass(zero) float @test_signed_basic_nsz(float %x) {
+; CHECK-LABEL: test_signed_basic_nsz:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    frintz s0, s0
+; CHECK-NEXT:    ret
 entry:
   %i = fptosi float %x to i32
   %f = sitofp i32 %i to float
@@ -26,16 +31,22 @@ entry:
 }
 
 define float @test_unsigned_basic(float %x) {
-; SIGNED-ZEROS-LABEL: test_unsigned_basic:
-; SIGNED-ZEROS:       // %bb.0: // %entry
-; SIGNED-ZEROS-NEXT:    fcvtzu s0, s0
-; SIGNED-ZEROS-NEXT:    ucvtf s0, s0
-; SIGNED-ZEROS-NEXT:    ret
-;
-; NO-SIGNED-ZEROS-LABEL: test_unsigned_basic:
-; NO-SIGNED-ZEROS:       // %bb.0: // %entry
-; NO-SIGNED-ZEROS-NEXT:    frintz s0, s0
-; NO-SIGNED-ZEROS-NEXT:    ret
+; CHECK-LABEL: test_unsigned_basic:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtzu s0, s0
+; CHECK-NEXT:    ucvtf s0, s0
+; CHECK-NEXT:    ret
+entry:
+  %i = fptoui float %x to i32
+  %f = uitofp i32 %i to float
+  ret float %f
+}
+
+define nofpclass(zero) float @test_unsigned_basic_nsz(float %x) {
+; CHECK-LABEL: test_unsigned_basic_nsz:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    frintz s0, s0
+; CHECK-NEXT:    ret
 entry:
   %i = fptoui float %x to i32
   %f = uitofp i32 %i to float
@@ -43,28 +54,36 @@ entry:
 }
 
 define float @test_signed_min_max(float %x) {
-; SIGNED-ZEROS-LABEL: test_signed_min_max:
-; SIGNED-ZEROS:       // %bb.0: // %entry
-; SIGNED-ZEROS-NEXT:    fcvtzs w9, s0
-; SIGNED-ZEROS-NEXT:    mov w8, #-512 // =0xfffffe00
-; SIGNED-ZEROS-NEXT:    cmn w9, #512
-; SIGNED-ZEROS-NEXT:    csel w8, w9, w8, gt
-; SIGNED-ZEROS-NEXT:    mov w9, #1023 // =0x3ff
-; SIGNED-ZEROS-NEXT:    cmp w8, #1023
-; SIGNED-ZEROS-NEXT:    csel w8, w8, w9, lt
-; SIGNED-ZEROS-NEXT:    scvtf s0, w8
-; SIGNED-ZEROS-NEXT:    ret
-;
-; NO-SIGNED-ZEROS-LABEL: test_signed_min_max:
-; NO-SIGNED-ZEROS:       // %bb.0: // %entry
-; NO-SIGNED-ZEROS-NEXT:    movi v1.2s, #196, lsl #24
-; NO-SIGNED-ZEROS-NEXT:    frintz s0, s0
-; NO-SIGNED-ZEROS-NEXT:    mov w8, #49152 // =0xc000
-; NO-SIGNED-ZEROS-NEXT:    movk w8, #17535, lsl #16
-; NO-SIGNED-ZEROS-NEXT:    fmaxnm s0, s0, s1
-; NO-SIGNED-ZEROS-NEXT:    fmov s1, w8
-; NO-SIGNED-ZEROS-NEXT:    fminnm s0, s0, s1
-; NO-SIGNED-ZEROS-NEXT:    ret
+; CHECK-LABEL: test_signed_min_max:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtzs w9, s0
+; CHECK-NEXT:    mov w8, #-512 // =0xfffffe00
+; CHECK-NEXT:    cmn w9, #512
+; CHECK-NEXT:    csel w8, w9, w8, gt
+; CHECK-NEXT:    mov w9, #1023 // =0x3ff
+; CHECK-NEXT:    cmp w8, #1023
+; CHECK-NEXT:    csel w8, w8, w9, lt
+; CHECK-NEXT:    scvtf s0, w8
+; CHECK-NEXT:    ret
+entry:
+  %i = fptosi float %x to i32
+  %lower = call i32 @llvm.smax.i32(i32 %i, i32 -512)
+  %clamped = call i32 @llvm.smin.i32(i32 %lower, i32 1023)
+  %f = sitofp i32 %clamped to float
+  ret float %f
+}
+
+define nofpclass(zero) float @test_signed_min_max_nsz(float %x) {
+; CHECK-LABEL: test_signed_min_max_nsz:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    movi v1.2s, #196, lsl #24
+; CHECK-NEXT:    frintz s0, s0
+; CHECK-NEXT:    mov w8, #49152 // =0xc000
+; CHECK-NEXT:    movk w8, #17535, lsl #16
+; CHECK-NEXT:    fmaxnm s0, s0, s1
+; CHECK-NEXT:    fmov s1, w8
+; CHECK-NEXT:    fminnm s0, s0, s1
+; CHECK-NEXT:    ret
 entry:
   %i = fptosi float %x to i32
   %lower = call i32 @llvm.smax.i32(i32 %i, i32 -512)
@@ -74,28 +93,36 @@ entry:
 }
 
 define float @test_unsigned_min_max(float %x) {
-; SIGNED-ZEROS-LABEL: test_unsigned_min_max:
-; SIGNED-ZEROS:       // %bb.0: // %entry
-; SIGNED-ZEROS-NEXT:    fcvtzu w9, s0
-; SIGNED-ZEROS-NEXT:    mov w8, #512 // =0x200
-; SIGNED-ZEROS-NEXT:    cmp w9, #512
-; SIGNED-ZEROS-NEXT:    csel w8, w9, w8, hi
-; SIGNED-ZEROS-NEXT:    mov w9, #1023 // =0x3ff
-; SIGNED-ZEROS-NEXT:    cmp w8, #1023
-; SIGNED-ZEROS-NEXT:    csel w8, w8, w9, lo
-; SIGNED-ZEROS-NEXT:    ucvtf s0, w8
-; SIGNED-ZEROS-NEXT:    ret
-;
-; NO-SIGNED-ZEROS-LABEL: test_unsigned_min_max:
-; NO-SIGNED-ZEROS:       // %bb.0: // %entry
-; NO-SIGNED-ZEROS-NEXT:    movi v1.2s, #68, lsl #24
-; NO-SIGNED-ZEROS-NEXT:    frintz s0, s0
-; NO-SIGNED-ZEROS-NEXT:    mov w8, #49152 // =0xc000
-; NO-SIGNED-ZEROS-NEXT:    movk w8, #17535, lsl #16
-; NO-SIGNED-ZEROS-NEXT:    fmaxnm s0, s0, s1
-; NO-SIGNED-ZEROS-NEXT:    fmov s1, w8
-; NO-SIGNED-ZEROS-NEXT:    fminnm s0, s0, s1
-; NO-SIGNED-ZEROS-NEXT:    ret
+; CHECK-LABEL: test_unsigned_min_max:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtzu w9, s0
+; CHECK-NEXT:    mov w8, #512 // =0x200
+; CHECK-NEXT:    cmp w9, #512
+; CHECK-NEXT:    csel w8, w9, w8, hi
+; CHECK-NEXT:    mov w9, #1023 // =0x3ff
+; CHECK-NEXT:    cmp w8, #1023
+; CHECK-NEXT:    csel w8, w8, w9, lo
+; CHECK-NEXT:    ucvtf s0, w8
+; CHECK-NEXT:    ret
+entry:
+  %i = fptoui float %x to i32
+  %lower = call i32 @llvm.umax.i32(i32 %i, i32 512)
+  %clamped = call i32 @llvm.umin.i32(i32 %lower, i32 1023)
+  %f = uitofp i32 %clamped to float
+  ret float %f
+}
+
+define nofpclass(zero) float @test_unsigned_min_max_nsz(float %x) {
+; CHECK-LABEL: test_unsigned_min_max_nsz:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    movi v1.2s, #68, lsl #24
+; CHECK-NEXT:    frintz s0, s0
+; CHECK-NEXT:    mov w8, #49152 // =0xc000
+; CHECK-NEXT:    movk w8, #17535, lsl #16
+; CHECK-NEXT:    fmaxnm s0, s0, s1
+; CHECK-NEXT:    fmov s1, w8
+; CHECK-NEXT:    fminnm s0, s0, s1
+; CHECK-NEXT:    ret
 entry:
   %i = fptoui float %x to i32
   %lower = call i32 @llvm.umax.i32(i32 %i, i32 512)
@@ -124,16 +151,22 @@ entry:
 }
 
 define <4 x float> @test_signed_v4f32(<4 x float> %x) {
-; SIGNED-ZEROS-LABEL: test_signed_v4f32:
-; SIGNED-ZEROS:       // %bb.0: // %entry
-; SIGNED-ZEROS-NEXT:    fcvtzs v0.4s, v0.4s
-; SIGNED-ZEROS-NEXT:    scvtf v0.4s, v0.4s
-; SIGNED-ZEROS-NEXT:    ret
-;
-; NO-SIGNED-ZEROS-LABEL: test_signed_v4f32:
-; NO-SIGNED-ZEROS:       // %bb.0: // %entry
-; NO-SIGNED-ZEROS-NEXT:    frintz v0.4s, v0.4s
-; NO-SIGNED-ZEROS-NEXT:    ret
+; CHECK-LABEL: test_signed_v4f32:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtzs v0.4s, v0.4s
+; CHECK-NEXT:    scvtf v0.4s, v0.4s
+; CHECK-NEXT:    ret
+entry:
+  %i = fptosi <4 x float> %x to <4 x i32>
+  %f = sitofp <4 x i32> %i to <4 x float>
+  ret <4 x float> %f
+}
+
+define nofpclass(zero) <4 x float> @test_signed_v4f32_nsz(<4 x float> %x) {
+; CHECK-LABEL: test_signed_v4f32_nsz:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    frintz v0.4s, v0.4s
+; CHECK-NEXT:    ret
 entry:
   %i = fptosi <4 x float> %x to <4 x i32>
   %f = sitofp <4 x i32> %i to <4 x float>
@@ -141,16 +174,22 @@ entry:
 }
 
 define <4 x float> @test_unsigned_v4f32(<4 x float> %x) {
-; SIGNED-ZEROS-LABEL: test_unsigned_v4f32:
-; SIGNED-ZEROS:       // %bb.0: // %entry
-; SIGNED-ZEROS-NEXT:    fcvtzu v0.4s, v0.4s
-; SIGNED-ZEROS-NEXT:    ucvtf v0.4s, v0.4s
-; SIGNED-ZEROS-NEXT:    ret
-;
-; NO-SIGNED-ZEROS-LABEL: test_unsigned_v4f32:
-; NO-SIGNED-ZEROS:       // %bb.0: // %entry
-; NO-SIGNED-ZEROS-NEXT:    frintz v0.4s, v0.4s
-; NO-SIGNED-ZEROS-NEXT:    ret
+; CHECK-LABEL: test_unsigned_v4f32:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
+; CHECK-NEXT:    ucvtf v0.4s, v0.4s
+; CHECK-NEXT:    ret
+entry:
+  %i = fptoui <4 x float> %x to <4 x i32>
+  %f = uitofp <4 x i32> %i to <4 x float>
+  ret <4 x float> %f
+}
+
+define nofpclass(zero) <4 x float> @test_unsigned_v4f32_nsz(<4 x float> %x) {
+; CHECK-LABEL: test_unsigned_v4f32_nsz:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    frintz v0.4s, v0.4s
+; CHECK-NEXT:    ret
 entry:
   %i = fptoui <4 x float> %x to <4 x i32>
   %f = uitofp <4 x i32> %i to <4 x float>
@@ -158,16 +197,22 @@ entry:
 }
 
 define <2 x double> @test_signed_v2f64(<2 x double> %x) {
-; SIGNED-ZEROS-LABEL: test_signed_v2f64:
-; SIGNED-ZEROS:       // %bb.0: // %entry
-; SIGNED-ZEROS-NEXT:    fcvtzs v0.2d, v0.2d
-; SIGNED-ZEROS-NEXT:    scvtf v0.2d, v0.2d
-; SIGNED-ZEROS-NEXT:    ret
-;
-; NO-SIGNED-ZEROS-LABEL: test_signed_v2f64:
-; NO-SIGNED-ZEROS:       // %bb.0: // %entry
-; NO-SIGNED-ZEROS-NEXT:    frintz v0.2d, v0.2d
-; NO-SIGNED-ZEROS-NEXT:    ret
+; CHECK-LABEL: test_signed_v2f64:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
+; CHECK-NEXT:    scvtf v0.2d, v0.2d
+; CHECK-NEXT:    ret
+entry:
+  %i = fptosi <2 x double> %x to <2 x i64>
+  %f = sitofp <2 x i64> %i to <2 x double>
+  ret <2 x double> %f
+}
+
+define nofpclass(zero) <2 x double> @test_signed_v2f64_nsz(<2 x double> %x) {
+; CHECK-LABEL: test_signed_v2f64_nsz:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    frintz v0.2d, v0.2d
+; CHECK-NEXT:    ret
 entry:
   %i = fptosi <2 x double> %x to <2 x i64>
   %f = sitofp <2 x i64> %i to <2 x double>
@@ -175,16 +220,22 @@ entry:
 }
 
 define <2 x double> @test_unsigned_v2f64(<2 x double> %x) {
-; SIGNED-ZEROS-LABEL: test_unsigned_v2f64:
-; SIGNED-ZEROS:       // %bb.0: // %entry
-; SIGNED-ZEROS-NEXT:    fcvtzu v0.2d, v0.2d
-; SIGNED-ZEROS-NEXT:    ucvtf v0.2d, v0.2d
-; SIGNED-ZEROS-NEXT:    ret
-;
-; NO-SIGNED-ZEROS-LABEL: test_unsigned_v2f64:
-; NO-SIGNED-ZEROS:       // %bb.0: // %entry
-; NO-SIGNED-ZEROS-NEXT:    frintz v0.2d, v0.2d
-; NO-SIGNED-ZEROS-NEXT:    ret
+; CHECK-LABEL: test_unsigned_v2f64:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtzu v0.2d, v0.2d
+; CHECK-NEXT:    ucvtf v0.2d, v0.2d
+; CHECK-NEXT:    ret
+entry:
+  %i = fptoui <2 x double> %x to <2 x i64>
+  %f = uitofp <2 x i64> %i to <2 x double>
+  ret <2 x double> %f
+}
+
+define nofpclass(zero) <2 x double> @test_unsigned_v2f64_nsz(<2 x double> %x) {
+; CHECK-LABEL: test_unsigned_v2f64_nsz:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    frintz v0.2d, v0.2d
+; CHECK-NEXT:    ret
 entry:
   %i = fptoui <2 x double> %x to <2 x i64>
   %f = uitofp <2 x i64> %i to <2 x double>
@@ -192,26 +243,34 @@ entry:
 }
 
 define <4 x float> @test_signed_v4f32_min_max(<4 x float> %x) {
-; SIGNED-ZEROS-LABEL: test_signed_v4f32_min_max:
-; SIGNED-ZEROS:       // %bb.0: // %entry
-; SIGNED-ZEROS-NEXT:    fcvtzs v0.4s, v0.4s
-; SIGNED-ZEROS-NEXT:    mvni v1.4s, #1, msl #8
-; SIGNED-ZEROS-NEXT:    smax v0.4s, v0.4s, v1.4s
-; SIGNED-ZEROS-NEXT:    movi v1.4s, #3, msl #8
-; SIGNED-ZEROS-NEXT:    smin v0.4s, v0.4s, v1.4s
-; SIGNED-ZEROS-NEXT:    scvtf v0.4s, v0.4s
-; SIGNED-ZEROS-NEXT:    ret
-;
-; NO-SIGNED-ZEROS-LABEL: test_signed_v4f32_min_max:
-; NO-SIGNED-ZEROS:       // %bb.0: // %entry
-; NO-SIGNED-ZEROS-NEXT:    movi v1.4s, #196, lsl #24
-; NO-SIGNED-ZEROS-NEXT:    frintz v0.4s, v0.4s
-; NO-SIGNED-ZEROS-NEXT:    mov w8, #49152 // =0xc000
-; NO-SIGNED-ZEROS-NEXT:    movk w8, #17535, lsl #16
-; NO-SIGNED-ZEROS-NEXT:    fmaxnm v0.4s, v0.4s, v1.4s
-; NO-SIGNED-ZEROS-NEXT:    dup v1.4s, w8
-; NO-SIGNED-ZEROS-NEXT:    fminnm v0.4s, v0.4s, v1.4s
-; NO-SIGNED-ZEROS-NEXT:    ret
+; CHECK-LABEL: test_signed_v4f32_min_max:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    fcvtzs v0.4s, v0.4s
+; CHECK-NEXT:    mvni v1.4s, #1, msl #8
+; CHECK-NEXT:    smax v0.4s, v0.4s, v1.4s
+; CHECK-NEXT:    movi v1.4s, #3, msl #8
+; CHECK-NEXT:    smin v0.4s, v0.4s, v1.4s
+; CHECK-NEXT:    scvtf v0.4s, v0.4s
+; CHECK-NEXT:    ret
+entry:
+  %i = fptosi <4 x float> %x to <4 x i32>
+  %lower = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %i, <4 x i32> splat (i32 -512))
+  %clamped = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %lower, <4 x i32> splat (i32 1023))
+  %f = sitofp <4 x i32> %clamped to <4 x float>
+  ret <4 x float> %f
+}
+
+define nofpclass(zero) <4 x float> @test_signed_v4f32_min_max_nsz(<4 x float> %x) {
+; CHECK-LABEL: test_signed_v4f32_min_max_nsz:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    movi v1.4s, #196, lsl #24
+; CHECK-NEXT:    frintz v0.4s, v0.4s
+; CHECK-NEXT:    mov w8, #49152 // =0xc000
+; CHECK-NEXT:    movk w8, #17535, lsl #16
+; CHECK-NEXT:    fmaxnm v0.4s, v0.4s, v1.4s
+; CHECK-NEXT:    dup v1.4s, w8
+; CHECK-NEXT:    fminnm v0.4s, v0.4s, v1.4s
+; CHECK-NEXT:    ret
 entry:
   %i = fptosi <4 x float> %x to <4 x i32>
   %lower = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %i, <4 x i32> splat (i32 -512))
@@ -221,26 +280,34 @@ entry:
 }
 
 define <4 x float> @test_unsigned_v4f32_min_max(<4 x float> %x) {
-; SIGNED-ZEROS-LABEL: test_unsigned_v4f32_min_max:
-; SIGNED-ZEROS:       // %bb.0: // %entry
-; SIGNED-ZEROS-NEXT:    movi v1.4s, #2, lsl #8
-; SIGNED-ZEROS-NEXT:    fcvtzu v0.4s, v0.4s
-; SIGNED-ZEROS-NEXT:    umax v0.4s, v0.4s, v1.4s
-; SIGNED-ZEROS-NEXT:    movi v1.4s, #3, msl #8
-; SIGNED-ZEROS-NEXT:    umin v0.4s, v0.4s, v1.4s
-; SIGNED-ZEROS-NEXT:    ucvtf v0.4s, v0.4s
-; SIGNED-ZEROS-NEXT:    ret
-;
-; NO-SIGNED-ZEROS-LABEL: test_unsigned_v4f32_min_max:
-; NO-SIGNED-ZEROS:       // %bb.0: // %entry
-; NO-SIGNED-ZEROS-NEXT:    movi v1.4s, #68, lsl #24
-; NO-SIGNED-ZEROS-NEXT:    frintz v0.4s, v0.4s
-; NO-SIGNED-ZEROS-NEXT:    mov w8, #49152 // =0xc000
-; NO-SIGNED-ZEROS-NEXT:    movk w8, #17535, lsl #16
-; NO-SIGNED-ZEROS-NEXT:    fmaxnm v0.4s, v0.4s, v1.4s
-; NO-SIGNED-ZEROS-NEXT:    dup v1.4s, w8
-; NO-SIGNED-ZEROS-NEXT:    fminnm v0.4s, v0.4s, v1.4s
-; NO-SIGNED-ZEROS-NEXT:    ret
+; CHECK-LABEL: test_unsigned_v4f32_min_max:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    movi v1.4s, #2, lsl #8
+; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
+; CHECK-NEXT:    umax v0.4s, v0.4s, v1.4s
+; CHECK-NEXT:    movi v1.4s, #3, msl #8
+; CHECK-NEXT:    umin v0.4s, v0.4s, v1.4s
+; CHECK-NEXT:    ucvtf v0.4s, v0.4s
+; CHECK-NEXT:    ret
+entry:
+  %i = fptoui <4 x float> %x to <4 x i32>
+  %lower = call <4 x i32> @llvm.umax.v4i32(<4 x i32> %i, <4 x i32> splat (i32 512))
+  %clamped = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %lower, <4 x i32> splat (i32 1023))
+  %f = uitofp <4 x i32> %clamped to <4 x float>
+  ret <4 x float> %f
+}
+
+define nofpclass(zero) <4 x float> @test_unsigned_v4f32_min_max_nsz(<4 x float> %x) {
+; CHECK-LABEL: test_unsigned_v4f32_min_max_nsz:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    movi v1.4s, #68, lsl #24
+; CHECK-NEXT:    frintz v0.4s, v0.4s
+; CHECK-NEXT:    mov w8, #49152 // =0xc000
+; CHECK-NEXT:    movk w8, #17535, lsl #16
+; CHECK-NEXT:    fmaxnm v0.4s, v0.4s, v1.4s
+; CHECK-NEXT:    dup v1.4s, w8
+; CHECK-NEXT:    fminnm v0.4s, v0.4s, v1.4s
+; CHECK-NEXT:    ret
 entry:
   %i = fptoui <4 x float> %x to <4 x i32>
   %lower = call <4 x i32> @llvm.umax.v4i32(<4 x i32> %i, <4 x i32> splat (i32 512))
diff --git a/llvm/test/CodeGen/AArch64/ftrunc.ll b/llvm/test/CodeGen/AArch64/ftrunc.ll
index c7bf514e902be..46444cb564a17 100644
--- a/llvm/test/CodeGen/AArch64/ftrunc.ll
+++ b/llvm/test/CodeGen/AArch64/ftrunc.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc -mtriple=aarch64-unknown-unknown < %s | FileCheck %s
 
-define float @trunc_unsigned_f32(float %x) #0 {
+define nofpclass(zero) float @trunc_unsigned_f32(float %x) {
 ; CHECK-LABEL: trunc_unsigned_f32:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    frintz s0, s0
@@ -11,7 +11,7 @@ define float @trunc_unsigned_f32(float %x) #0 {
   ret float %r
 }
 
-define double @trunc_unsigned_f64(double %x) #0 {
+define nofpclass(zero) double @trunc_unsigned_f64(double %x) {
 ; CHECK-LABEL: trunc_unsigned_f64:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    frintz d0, d0
@@ -21,7 +21,7 @@ define double @trunc_unsigned_f64(double %x) #0 {
   ret double %r
 }
 
-define float @trunc_signed_f32(float %x) #0 {
+define nofpclass(zero) float @trunc_signed_f32(float %x) {
 ; CHECK-LABEL: trunc_signed_f32:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    frintz s0, s0
@@ -31,7 +31,7 @@ define float @trunc_signed_f32(float %x) #0 {
   ret float %r
 }
 
-define double @trunc_signed_f64(double %x) #0 {
+define nofpclass(zero) double @trunc_signed_f64(double %x) {
 ; CHECK-LABEL: trunc_signed_f64:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    frintz d0, d0
@@ -40,6 +40,3 @@ define double @trunc_signed_f64(double %x) #0 {
   %r = sitofp i64 %i to double
   ret double %r
 }
-
-attributes #0 = { "no-signed-zeros-fp-math"="true" }
-
diff --git a/llvm/test/CodeGen/AMDGPU/fp-to-int-to-fp.ll b/llvm/test/CodeGen/AMDGPU/fp-to-int-to-fp.ll
index 2416d6a852eb9..cc1e9d2d8d129 100644
--- a/llvm/test/CodeGen/AMDGPU/fp-to-int-to-fp.ll
+++ b/llvm/test/CodeGen/AMDGPU/fp-to-int-to-fp.ll
@@ -1,22 +1,27 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=amdgcn < %s | FileCheck %s --check-prefixes=CHECK,SIGNED-ZEROS
-; RUN: llc -mtriple=amdgcn --enable-no-signed-zeros-fp-math < %s | FileCheck %s --check-prefixes=CHECK,NO-SIGNED-ZEROS
+; RUN: llc -mtriple=amdgcn < %s | FileCheck %s
 
 ; Test folding of float->int->float roundtrips into float-only operations.
 
 define float @test_signed_basic(float %x) {
-; SIGNED-ZEROS-LABEL: test_signed_basic:
-; SIGNED-ZEROS:       ; %bb.0: ; %entry
-; SIGNED-ZEROS-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; SIGNED-ZEROS-NEXT:    v_cvt_i32_f32_e32 v0, v0
-; SIGNED-ZEROS-NEXT:    v_cvt_f32_i32_e32 v0, v0
-; SIGNED-ZEROS-NEXT:    s_setpc_b64 s[30:31]
-;
-; NO-SIGNED-ZEROS-LABEL: test_signed_basic:
-; NO-SIGNED-ZEROS:       ; %bb.0: ; %entry
-; NO-SIGNED-ZEROS-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; NO-SIGNED-ZEROS-NEXT:    v_trunc_f32_e32 v0, v0
-; NO-SIGNED-ZEROS-NEXT:    s_setpc_b64 s[30:31]
+; CHECK-LABEL: test_signed_basic:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_cvt_i32_f32_e32 v0, v0
+; CHECK-NEXT:    v_cvt_f32_i32_e32 v0, v0
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %i = fptosi float %x to i32
+  %f = sitofp i32 %i to float
+  ret float %f
+}
+
+define nofpclass(zero) float @test_signed_basic_nsz(float %x) {
+; CHECK-LABEL: test_signed_basic_nsz:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_trunc_f32_e32 v0, v0
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
 entry:
   %i = fptosi float %x to i32
   %f = sitofp i32 %i to float
@@ -26,17 +31,23 @@ entry:
 ; For unsigned conversions, even when signed zeros are possible, we can still
 ; use truncate because fabs is free.
 define float @test_unsigned_basic(float %x) {
-; SIGNED-ZEROS-LABEL: test_unsigned_basic:
-; SIGNED-ZEROS:       ; %bb.0: ; %entry
-; SIGNED-ZEROS-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; SIGNED-ZEROS-NEXT:    v_trunc_f32_e64 v0, |v0|
-; SIGNED-ZEROS-NEXT:    s_setpc_b64 s[30:31]
-;
-; NO-SIGNED-ZEROS-LABEL: test_unsigned_basic:
-; NO-SIGNED-ZEROS:       ; %bb.0: ; %entry
-; NO-SIGNED-ZEROS-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; NO-SIGNED-ZEROS-NEXT:    v_trunc_f32_e32 v0, v0
-; NO-SIGNED-ZEROS-NEXT:    s_setpc_b64 s[30:31]
+; CHECK-LABEL: test_unsigned_basic:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_trunc_f32_e64 v0, |v0|
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %i = fptoui float %x to i32
+  %f = uitofp i32 %i to float
+  ret float %f
+}
+
+define nofpclass(zero) float @test_unsigned_basic_nsz(float %x) {
+; CHECK-LABEL: test_unsigned_basic_nsz:
+; CHECK:       ; %bb.0: ; %entry
+; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; CHECK-NEXT:    v_trunc_f32_e32 v0, v0
+; CHECK-NEXT:    s_setpc_b64 s[30:31]
 entry:
   %i = fptoui float %x to i32
   %f = uitofp i32 %i to float
diff --git a/llvm/test/CodeGen/PowerPC/fp-int128-fp-combine.ll b/llvm/test/CodeGen/PowerPC/fp-int128-fp-combine.ll
index 8ebf54a3dc489..33f744b701ccd 100644
--- a/llvm/test/CodeGen/PowerPC/fp-int128-fp-combine.ll
+++ b/llvm/test/CodeGen/PowerPC/fp-int128-fp-combine.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -O0 -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
+; RUN: llc -O0 -mtriple=powerpc64le-unknown-linux-gnu -fast-isel=false < %s | FileCheck %s
 
 ; xscvdpsxds should NOT be emitted, since it saturates the result down to i64.
 ; We can't use friz here because it may return -0.0 where the original code doesn't.
@@ -26,7 +26,7 @@ entry:
 
 ; NSZ, so it's safe to friz.
 
-define float @f_i128_fi_nsz(float %v) #0 {
+define nofpclass(zero) float @f_i128_fi_nsz(float %v) {
 ; CHECK-LABEL: f_i128_fi_nsz:
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    xsrdpiz 1, 1
@@ -36,6 +36,3 @@ entry:
   %b = sitofp i128 %a to float
   ret float %b
 }
-
-attributes #0 = { "no-signed-zeros-fp-math"="true" }
-
diff --git a/llvm/test/CodeGen/PowerPC/fp-to-int-to-fp.ll b/llvm/test/CodeGen/PowerPC/fp-to-int-to-fp.ll
index 11460349c90fb..c5f6ee70f4918 100644
--- a/llvm/test/CodeGen/PowerPC/fp-to-int-to-fp.ll
+++ b/llvm/test/CodeGen/PowerPC/fp-to-int-to-fp.ll
@@ -6,7 +6,7 @@ target datalayout = "E-m:e-i64:64-n32:64"
 target triple = "powerpc64-unknown-linux-gnu"
 
 ; Function Attrs: nounwind readnone
-define float @fool(float %X) #0 {
+define nofpclass(zero) float @fool(float %X) #0 {
 ; FPCVT-LABEL: fool:
 ; FPCVT:       # %bb.0: # %entry
 ; FPCVT-NEXT:    friz 1, 1
@@ -32,7 +32,7 @@ entry:
 }
 
 ; Function Attrs: nounwind readnone
-define double @foodl(double %X) #0 {
+define nofpclass(zero) double @foodl(double %X) #0 {
 ; FPCVT-LABEL: foodl:
 ; FPCVT:       # %bb.0: # %entry
 ; FPCVT-NEXT:    friz 1, 1
@@ -57,7 +57,7 @@ entry:
 }
 
 ; Function Attrs: nounwind readnone
-define float @fooul(float %X) #0 {
+define nofpclass(zero) float @fooul(float %X) #0 {
 ; FPCVT-LABEL: fooul:
 ; FPCVT:       # %bb.0: # %entry
 ; FPCVT-NEXT:    friz 1, 1
@@ -138,7 +138,7 @@ entry:
 }
 
 ; Function Attrs: nounwind readnone
-define double @fooudl(double %X) #0 {
+define nofpclass(zero) double @fooudl(double %X) #0 {
 ; FPCVT-LABEL: fooudl:
 ; FPCVT:       # %bb.0: # %entry
 ; FPCVT-NEXT:    friz 1, 1
@@ -323,5 +323,5 @@ entry:
   ret double %conv
 
 }
-attributes #0 = { nounwind readnone "no-signed-zeros-fp-math"="true" }
+attributes #0 = { nounwind readnone }
 
diff --git a/llvm/test/CodeGen/PowerPC/ftrunc-vec.ll b/llvm/test/CodeGen/PowerPC/ftrunc-vec.ll
index ecad35d22e859..af2f95b185c8b 100644
--- a/llvm/test/CodeGen/PowerPC/ftrunc-vec.ll
+++ b/llvm/test/CodeGen/PowerPC/ftrunc-vec.ll
@@ -2,7 +2,7 @@
 ; RUN: llc -mcpu=pwr8 -mtriple=powerpc64le-unknown-unknown -verify-machineinstrs < %s | FileCheck %s
 ; RUN: llc -mcpu=pwr8 -mtriple=powerpc64-ibm-aix-xcoff -vec-extabi -verify-machineinstrs < %s | FileCheck %s
 
-define <4 x float> @truncf32(<4 x float> %a) #0 {
+define nofpclass(zero) <4 x float> @truncf32(<4 x float> %a) {
 ; CHECK-LABEL: truncf32:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xvrspiz 34, 34
@@ -12,7 +12,7 @@ define <4 x float> @truncf32(<4 x float> %a) #0 {
   ret <4 x float> %t1
 }
 
-define <2 x double> @truncf64(<2 x double> %a) #0 {
+define nofpclass(zero) <2 x double> @truncf64(<2 x double> %a) {
 ; CHECK-LABEL: truncf64:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xvrdpiz 34, 34
@@ -22,7 +22,7 @@ define <2 x double> @truncf64(<2 x double> %a) #0 {
   ret <2 x double> %t1
 }
 
-define <4 x float> @truncf32u(<4 x float> %a) #0 {
+define nofpclass(zero) <4 x float> @truncf32u(<4 x float> %a) {
 ; CHECK-LABEL: truncf32u:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xvrspiz 34, 34
@@ -32,7 +32,7 @@ define <4 x float> @truncf32u(<4 x float> %a) #0 {
   ret <4 x float> %t1
 }
 
-define <2 x double> @truncf64u(<2 x double> %a) #0 {
+define nofpclass(zero) <2 x double> @truncf64u(<2 x double> %a) {
 ; CHECK-LABEL: truncf64u:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    xvrdpiz 34, 34
@@ -41,6 +41,3 @@ define <2 x double> @truncf64u(<2 x double> %a) #0 {
   %t1 = uitofp <2 x i64> %t0 to <2 x double>
   ret <2 x double> %t1
 }
-
-attributes #0 = { "no-signed-zeros-fp-math"="true" }
-
diff --git a/llvm/test/CodeGen/PowerPC/no-extra-fp-conv-ldst.ll b/llvm/test/CodeGen/PowerPC/no-extra-fp-conv-ldst.ll
index 3ce14d35c4aea..dee313650b7d0 100644
--- a/llvm/test/CodeGen/PowerPC/no-extra-fp-conv-ldst.ll
+++ b/llvm/test/CodeGen/PowerPC/no-extra-fp-conv-ldst.ll
@@ -3,7 +3,7 @@ target datalayout = "E-m:e-i64:64-n32:64"
 target triple = "powerpc64-unknown-linux-gnu"
 
 ; Function Attrs: nounwind readonly
-define double @test1(ptr nocapture readonly %x) #0 {
+define nofpclass(zero) double @test1(ptr nocapture readonly %x) #0 {
 entry:
   %0 = load i64, ptr %x, align 8
   %conv = sitofp i64 %0 to double
@@ -16,7 +16,7 @@ entry:
 }
 
 ; Function Attrs: nounwind readonly
-define double @test2(ptr nocapture readonly %x) #0 {
+define nofpclass(zero) double @test2(ptr nocapture readonly %x) #0 {
 entry:
   %0 = load i32, ptr %x, align 4
   %conv = sitofp i32 %0 to double
@@ -29,7 +29,7 @@ entry:
 }
 
 ; Function Attrs: nounwind readnone
-define float @foo(float %X) #0 {
+define nofpclass(zero) float @foo(float %X) #0 {
 entry:
   %conv = fptosi float %X to i32
   %conv1 = sitofp i32 %conv to float
@@ -41,7 +41,7 @@ entry:
 }
 
 ; Function Attrs: nounwind readnone
-define double @food(double %X) #0 {
+define nofpclass(zero) double @food(double %X) #0 {
 entry:
   %conv = fptosi double %X to i32
   %conv1 = sitofp i32 %conv to double
@@ -53,7 +53,7 @@ entry:
 }
 
 ; Function Attrs: nounwind readnone
-define float @foou(float %X) #0 {
+define nofpclass(zero) float @foou(float %X) #0 {
 entry:
   %conv = fptoui float %X to i32
   %conv1 = uitofp i32 %conv to float
@@ -65,7 +65,7 @@ entry:
 }
 
 ; Function Attrs: nounwind readnone
-define double @fooud(double %X) #0 {
+define nofpclass(zero) double @fooud(double %X) #0 {
 entry:
   %conv = fptoui double %X to i32
   %conv1 = uitofp i32 %conv to double
@@ -76,5 +76,5 @@ entry:
 ; CHECK: blr
 }
 
-attributes #0 = { nounwind readonly "no-signed-zeros-fp-math"="true" }
+attributes #0 = { nounwind readonly }
 
diff --git a/llvm/test/CodeGen/X86/ftrunc.ll b/llvm/test/CodeGen/X86/ftrunc.ll
index 9095fb1550e70..11980b8d9b031 100644
--- a/llvm/test/CodeGen/X86/ftrunc.ll
+++ b/llvm/test/CodeGen/X86/ftrunc.ll
@@ -7,7 +7,7 @@
 declare i32 @llvm.fptoui.sat.i32.f32(float)
 declare i64 @llvm.fptosi.sat.i64.f64(double)
 
-define float @trunc_unsigned_f32(float %x) #0 {
+define nofpclass(zero) float @trunc_unsigned_f32(float %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_f32:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    cvttss2si %xmm0, %rax
@@ -40,7 +40,7 @@ define float @trunc_unsigned_f32(float %x) #0 {
   ret float %r
 }
 
-define double @trunc_unsigned_f64(double %x) #0 {
+define nofpclass(zero) double @trunc_unsigned_f64(double %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_f64:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    cvttsd2si %xmm0, %rax
@@ -86,7 +86,7 @@ define double @trunc_unsigned_f64(double %x) #0 {
   ret double %r
 }
 
-define <4 x float> @trunc_unsigned_v4f32(<4 x float> %x) #0 {
+define nofpclass(zero) <4 x float> @trunc_unsigned_v4f32(<4 x float> %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_v4f32:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    cvttps2dq %xmm0, %xmm1
@@ -119,7 +119,7 @@ define <4 x float> @trunc_unsigned_v4f32(<4 x float> %x) #0 {
   ret <4 x float> %r
 }
 
-define <2 x double> @trunc_unsigned_v2f64(<2 x double> %x) #0 {
+define nofpclass(zero) <2 x double> @trunc_unsigned_v2f64(<2 x double> %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_v2f64:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    movsd {{.*#+}} xmm2 = [9.2233720368547758E+18,0.0E+0]
@@ -166,7 +166,7 @@ define <2 x double> @trunc_unsigned_v2f64(<2 x double> %x) #0 {
   ret <2 x double> %r
 }
 
-define <4 x double> @trunc_unsigned_v4f64(<4 x double> %x) #0 {
+define nofpclass(zero) <4 x double> @trunc_unsigned_v4f64(<4 x double> %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_v4f64:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    movapd %xmm1, %xmm2
@@ -273,7 +273,7 @@ define float @trunc_signed_f32_no_fast_math(float %x) nounwind {
 
 ; Without -0.0, it is ok to use roundss if it is available.
 
-define float @trunc_signed_f32_nsz(float %x) #0 {
+define nofpclass(zero) float @trunc_signed_f32_nsz(float %x) #0 {
 ; SSE2-LABEL: trunc_signed_f32_nsz:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
@@ -336,7 +336,7 @@ define double @trunc_signed32_f64_no_fast_math(double %x) nounwind {
   ret double %r
 }
 
-define double @trunc_signed32_f64_nsz(double %x) #0 {
+define nofpclass(zero) double @trunc_signed32_f64_nsz(double %x) #0 {
 ; SSE2-LABEL: trunc_signed32_f64_nsz:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    cvttpd2dq %xmm0, %xmm0
@@ -371,7 +371,7 @@ define double @trunc_signed32_f64_nsz(double %x) #0 {
   ret double %r
 }
 
-define double @trunc_f32_signed32_f64_no_fast_math(float %x) nounwind {
+define nofpclass(zero) double @trunc_f32_signed32_f64_no_fast_math(float %x) nounwind {
 ; SSE-LABEL: trunc_f32_signed32_f64_no_fast_math:
 ; SSE:       # %bb.0:
 ; SSE-NEXT:    cvttps2dq %xmm0, %xmm0
@@ -393,7 +393,7 @@ define double @trunc_f32_signed32_f64_no_fast_math(float %x) nounwind {
 ; X86-AVX1-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-AVX1-NEXT:    vcvttps2dq %xmm0, %xmm0
 ; X86-AVX1-NEXT:    vcvtdq2pd %xmm0, %xmm0
-; X86-AVX1-NEXT:    vmovlps %xmm0, (%esp)
+; X86-AVX1-NEXT:    vmovsd %xmm0, (%esp)
 ; X86-AVX1-NEXT:    fldl (%esp)
 ; X86-AVX1-NEXT:    movl %ebp, %esp
 ; X86-AVX1-NEXT:    popl %ebp
@@ -528,7 +528,7 @@ define double @trunc_signed_f64_no_fast_math(double %x) nounwind {
   ret double %r
 }
 
-define double @trunc_signed_f64_nsz(double %x) #0 {
+define nofpclass(zero) double @trunc_signed_f64_nsz(double %x) #0 {
 ; SSE2-LABEL: trunc_signed_f64_nsz:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    cvttsd2si %xmm0, %rax
@@ -564,7 +564,7 @@ define double @trunc_signed_f64_nsz(double %x) #0 {
   ret double %r
 }
 
-define <4 x float> @trunc_signed_v4f32_nsz(<4 x float> %x) #0 {
+define nofpclass(zero) <4 x float> @trunc_signed_v4f32_nsz(<4 x float> %x) #0 {
 ; SSE2-LABEL: trunc_signed_v4f32_nsz:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
@@ -585,7 +585,7 @@ define <4 x float> @trunc_signed_v4f32_nsz(<4 x float> %x) #0 {
   ret <4 x float> %r
 }
 
-define <2 x double> @trunc_signed_v2f64_nsz(<2 x double> %x) #0 {
+define nofpclass(zero) <2 x double> @trunc_signed_v2f64_nsz(<2 x double> %x) #0 {
 ; SSE2-LABEL: trunc_signed_v2f64_nsz:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    cvttsd2si %xmm0, %rax
@@ -611,7 +611,7 @@ define <2 x double> @trunc_signed_v2f64_nsz(<2 x double> %x) #0 {
   ret <2 x double> %r
 }
 
-define <4 x double> @trunc_signed_v4f64_nsz(<4 x double> %x) #0 {
+define nofpclass(zero) <4 x double> @trunc_signed_v4f64_nsz(<4 x double> %x) #0 {
 ; SSE2-LABEL: trunc_signed_v4f64_nsz:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    cvttsd2si %xmm1, %rax
@@ -782,4 +782,4 @@ define double @trunc_signed_f64_disable_via_intrinsic(double %x) #0 {
   ret double %r
 }
 
-attributes #0 = { nounwind "no-signed-zeros-fp-math"="true" }
+attributes #0 = { nounwind }



More information about the llvm-commits mailing list