Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -13821,7 +13821,7 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, SDValue RHS) { - // fold (select (setcc x, -0.0, *lt), NaN, (fsqrt x)) + // fold (select (setcc x, [+-]0.0, *lt), NaN, (fsqrt x)) // The select + setcc is redundant, because fsqrt returns NaN for X < -0. if (const ConstantFPSDNode *NaN = isConstOrConstSplatFP(LHS)) { if (NaN->isNaN() && RHS.getOpcode() == ISD::FSQRT) { @@ -13829,22 +13829,22 @@ SDValue Sqrt = RHS; ISD::CondCode CC; SDValue CmpLHS; - const ConstantFPSDNode *NegZero = nullptr; + const ConstantFPSDNode *Zero = nullptr; if (TheSelect->getOpcode() == ISD::SELECT_CC) { CC = dyn_cast(TheSelect->getOperand(4))->get(); CmpLHS = TheSelect->getOperand(0); - NegZero = isConstOrConstSplatFP(TheSelect->getOperand(1)); + Zero = isConstOrConstSplatFP(TheSelect->getOperand(1)); } else { // SELECT or VSELECT SDValue Cmp = TheSelect->getOperand(0); if (Cmp.getOpcode() == ISD::SETCC) { CC = dyn_cast(Cmp.getOperand(2))->get(); CmpLHS = Cmp.getOperand(0); - NegZero = isConstOrConstSplatFP(Cmp.getOperand(1)); + Zero = isConstOrConstSplatFP(Cmp.getOperand(1)); } } - if (NegZero && NegZero->isNegative() && NegZero->isZero() && + if (Zero && Zero->isZero() && Sqrt.getOperand(0) == CmpLHS && (CC == ISD::SETOLT || CC == ISD::SETULT || CC == ISD::SETLT)) { // We have: (select (setcc x, -0.0, *lt), NaN, (fsqrt x)) Index: test/CodeGen/AMDGPU/llvm.sqrt.ll =================================================================== --- test/CodeGen/AMDGPU/llvm.sqrt.ll +++ test/CodeGen/AMDGPU/llvm.sqrt.ll @@ -50,10 +50,10 @@ ret void } -; SI-LABEL: {{^}}elim_redun_check: +; SI-LABEL: {{^}}elim_redun_check_neg0: ; SI: v_sqrt_f32_e32 ; SI-NOT: v_cndmask -define void @elim_redun_check(float addrspace(1)* %out, float %in) { +define void @elim_redun_check_neg0(float addrspace(1)* %out, float %in) { entry: %sqrt = call float @llvm.sqrt.f32(float %in) %cmp = fcmp olt float %in, -0.000000e+00 @@ -62,6 +62,18 @@ ret void } +; SI-LABEL: {{^}}elim_redun_check_pos0: +; SI: v_sqrt_f32_e32 +; SI-NOT: v_cndmask +define void @elim_redun_check_pos0(float addrspace(1)* %out, float %in) { +entry: + %sqrt = call float @llvm.sqrt.f32(float %in) + %cmp = fcmp olt float %in, 0.000000e+00 + %res = select i1 %cmp, float 0x7FF8000000000000, float %sqrt + store float %res, float addrspace(1)* %out + ret void +} + ; SI-LABEL: {{^}}elim_redun_check_ult: ; SI: v_sqrt_f32_e32 ; SI-NOT: v_cndmask