Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -4288,10 +4288,21 @@ return nullptr; // Unary Ops - if (NumOperands == 1) - if (IntrinsicInst *II = dyn_cast(*ArgBegin)) + if (NumOperands == 1) { + if (IntrinsicInst *II = dyn_cast(*ArgBegin)) { if (II->getIntrinsicID() == IID) return II; + } + + switch (IID) { + case Intrinsic::fabs: { + if (CannotBeOrderedLessThanZero(*ArgBegin, Q.TLI)) + return *ArgBegin; + } + default: + break; + } + } return nullptr; } Index: test/Transforms/InstSimplify/floating-point-arithmetic.ll =================================================================== --- test/Transforms/InstSimplify/floating-point-arithmetic.ll +++ test/Transforms/InstSimplify/floating-point-arithmetic.ll @@ -103,3 +103,44 @@ ret float %7 } +declare float @llvm.fabs.f32(float) + +; CHECK-LABEL: @fabs_select_positive_constants( +; CHECK: %select = select i1 %cmp, float 1.000000e+00, float 2.000000e+00 +; CHECK-NEXT: ret float %select +define float @fabs_select_positive_constants(i32 %c) { + %cmp = icmp eq i32 %c, 0 + %select = select i1 %cmp, float 1.0, float 2.0 + %fabs = call float @llvm.fabs.f32(float %select) + ret float %fabs +} + +; CHECK-LABEL: @fabs_select_constant_variable( +; CHECK: %select = select i1 %cmp, float 1.000000e+00, float %x +; CHECK-NEXT: %fabs = call float @llvm.fabs.f32(float %select) +define float @fabs_select_constant_variable(i32 %c, float %x) { + %cmp = icmp eq i32 %c, 0 + %select = select i1 %cmp, float 1.0, float %x + %fabs = call float @llvm.fabs.f32(float %select) + ret float %fabs +} + +; CHECK-LABEL: @fabs_select_neg0_pos0( +; CHECK: %select = select i1 %cmp, float -0.000000e+00, float 0.000000e+00 +; CHECK-NEXT: ret float %select +define float @fabs_select_neg0_pos0(float addrspace(1)* %out, i32 %c) { + %cmp = icmp eq i32 %c, 0 + %select = select i1 %cmp, float -0.0, float 0.0 + %fabs = call float @llvm.fabs.f32(float %select) + ret float %fabs +} + +; CHECK-LABEL: @fabs_select_neg0_neg1( +; CHECK: %select = select i1 %cmp, float -0.000000e+00, float -1.000000e+00 +; CHECK: %fabs = call float @llvm.fabs.f32(float %select) +define float @fabs_select_neg0_neg1(float addrspace(1)* %out, i32 %c) { + %cmp = icmp eq i32 %c, 0 + %select = select i1 %cmp, float -0.0, float -1.0 + %fabs = call float @llvm.fabs.f32(float %select) + ret float %fabs +}