Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -7337,6 +7337,18 @@ } } + // Fold (bitcast int (and (bitcast fp X to int), 0x7fff...) to fp) -> fabs x + if (VT.isFloatingPoint() && !VT.isVector() && N0.getOpcode() == ISD::AND && + TLI.isOperationLegal(ISD::FABS, VT)) { + SDValue AndOp0 = N0->getOperand(0); + ConstantSDNode *AndOp1 = dyn_cast(N0->getOperand(1)); + if (AndOp1 && AndOp1->getAPIntValue().isMaxSignedValue() && + AndOp0.getOpcode() == ISD::BITCAST && + AndOp0->getOperand(0).getValueType() == VT) { + return DAG.getNode(ISD::FABS, SDLoc(N), VT, AndOp0->getOperand(0)); + } + } + // fold (bitconvert (fneg x)) -> (xor (bitconvert x), signbit) // fold (bitconvert (fabs x)) -> (and (bitconvert x), (not signbit)) // Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1570,24 +1570,6 @@ if (Instruction *CastedAnd = foldCastedBitwiseLogic(I)) return CastedAnd; - if (CastInst *Op0C = dyn_cast(Op0)) { - Value *Op0COp = Op0C->getOperand(0); - Type *SrcTy = Op0COp->getType(); - - // If we are masking off the sign bit of a floating-point value, convert - // this to the canonical fabs intrinsic call and cast back to integer. - // The backend should know how to optimize fabs(). - // TODO: This transform should also apply to vectors. - ConstantInt *CI; - if (isa(Op0C) && SrcTy->isFloatingPointTy() && - match(Op1, m_ConstantInt(CI)) && CI->isMaxValue(true)) { - Module *M = I.getModule(); - Function *Fabs = Intrinsic::getDeclaration(M, Intrinsic::fabs, SrcTy); - Value *Call = Builder->CreateCall(Fabs, Op0COp, "fabs"); - return CastInst::CreateBitOrPointerCast(Call, I.getType()); - } - } - { Value *X = nullptr; bool OpsSwapped = false; Index: test/CodeGen/AArch64/fcvt-int.ll =================================================================== --- test/CodeGen/AArch64/fcvt-int.ll +++ test/CodeGen/AArch64/fcvt-int.ll @@ -153,9 +153,7 @@ define double @bitcast_fabs(double %x) { ; CHECK-LABEL: bitcast_fabs: ; CHECK: ; BB#0: -; CHECK-NEXT: fmov x8, d0 -; CHECK-NEXT: and x8, x8, #0x7fffffffffffffff -; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: fabs d0, d0 ; CHECK-NEXT: ret ; %bc1 = bitcast double %x to i64 Index: test/CodeGen/PowerPC/fabs.ll =================================================================== --- test/CodeGen/PowerPC/fabs.ll +++ test/CodeGen/PowerPC/fabs.ll @@ -13,13 +13,7 @@ define float @bitcast_fabs(float %x) { ; CHECK-LABEL: bitcast_fabs: ; CHECK: ; BB#0: -; CHECK-NEXT: stfs f1, -8(r1) -; CHECK-NEXT: nop -; CHECK-NEXT: nop -; CHECK-NEXT: lwz r2, -8(r1) -; CHECK-NEXT: clrlwi r2, r2, 1 -; CHECK-NEXT: stw r2, -4(r1) -; CHECK-NEXT: lfs f1, -4(r1) +; CHECK-NEXT: fabs f1, f1 ; CHECK-NEXT: blr ; %bc1 = bitcast float %x to i32 Index: test/Transforms/InstCombine/and2.ll =================================================================== --- test/Transforms/InstCombine/and2.ll +++ test/Transforms/InstCombine/and2.ll @@ -103,45 +103,3 @@ ret i64 %add } -define i64 @fabs_double(double %x) { -; CHECK-LABEL: @fabs_double( -; CHECK-NEXT: %fabs = call double @llvm.fabs.f64(double %x) -; CHECK-NEXT: %and = bitcast double %fabs to i64 -; CHECK-NEXT: ret i64 %and - %bc = bitcast double %x to i64 - %and = and i64 %bc, 9223372036854775807 - ret i64 %and -} - -define i64 @fabs_double_swap(double %x) { -; CHECK-LABEL: @fabs_double_swap( -; CHECK-NEXT: %fabs = call double @llvm.fabs.f64(double %x) -; CHECK-NEXT: %and = bitcast double %fabs to i64 -; CHECK-NEXT: ret i64 %and - %bc = bitcast double %x to i64 - %and = and i64 9223372036854775807, %bc - ret i64 %and -} - -define i32 @fabs_float(float %x) { -; CHECK-LABEL: @fabs_float( -; CHECK-NEXT: %fabs = call float @llvm.fabs.f32(float %x) -; CHECK-NEXT: %and = bitcast float %fabs to i32 -; CHECK-NEXT: ret i32 %and - %bc = bitcast float %x to i32 - %and = and i32 %bc, 2147483647 - ret i32 %and -} - -; Make sure that only a bitcast is transformed. - -define i64 @fabs_double_not_bitcast(double %x) { -; CHECK-LABEL: @fabs_double_not_bitcast( -; CHECK-NEXT: %bc = fptoui double %x to i64 -; CHECK-NEXT: %and = and i64 %bc, 9223372036854775807 -; CHECK-NEXT: ret i64 %and - %bc = fptoui double %x to i64 - %and = and i64 %bc, 9223372036854775807 - ret i64 %and -} -