Skip to content

Commit 77ff99c

Browse files
nikictru
authored andcommitted
[ValueTracking] Fix CannotBeOrderedLessThanZero() for fdiv (PR58046)
When checking the RHS of fdiv, we should set the SignBitOnly flag, because a negative zero can become -Inf, which is ordered less than zero. Fixes llvm/llvm-project#58046. Differential Revision: https://reviews.llvm.org/D134876
1 parent 6ba100a commit 77ff99c

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

llvm/lib/Analysis/ValueTracking.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -3593,14 +3593,23 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
35933593
// Unsigned integers are always nonnegative.
35943594
case Instruction::UIToFP:
35953595
return true;
3596-
case Instruction::FMul:
35973596
case Instruction::FDiv:
3598-
// X * X is always non-negative or a NaN.
35993597
// X / X is always exactly 1.0 or a NaN.
36003598
if (I->getOperand(0) == I->getOperand(1) &&
36013599
(!SignBitOnly || cast<FPMathOperator>(I)->hasNoNaNs()))
36023600
return true;
36033601

3602+
// Set SignBitOnly for RHS, because X / -0.0 is -Inf (or NaN).
3603+
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly,
3604+
Depth + 1) &&
3605+
cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI,
3606+
/*SignBitOnly*/ true, Depth + 1);
3607+
case Instruction::FMul:
3608+
// X * X is always non-negative or a NaN.
3609+
if (I->getOperand(0) == I->getOperand(1) &&
3610+
(!SignBitOnly || cast<FPMathOperator>(I)->hasNoNaNs()))
3611+
return true;
3612+
36043613
LLVM_FALLTHROUGH;
36053614
case Instruction::FAdd:
36063615
case Instruction::FRem:

llvm/test/Transforms/InstSimplify/floating-point-compare.ll

+6-2
Original file line numberDiff line numberDiff line change
@@ -999,10 +999,14 @@ define <2 x i1> @known_positive_une_with_negative_constant_splat_vec(<2 x i32> %
999999
ret <2 x i1> %cmp
10001000
}
10011001

1002-
; FIXME: Miscompile.
1002+
; TODO: This could fold to true.
10031003
define i1 @pr58046(i64 %arg) {
10041004
; CHECK-LABEL: @pr58046(
1005-
; CHECK-NEXT: ret i1 false
1005+
; CHECK-NEXT: [[FP:%.*]] = uitofp i64 [[ARG:%.*]] to double
1006+
; CHECK-NEXT: [[MUL:%.*]] = fmul double -0.000000e+00, [[FP]]
1007+
; CHECK-NEXT: [[DIV:%.*]] = fdiv double 1.000000e+00, [[MUL]]
1008+
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[DIV]], 0xFFF0000000000000
1009+
; CHECK-NEXT: ret i1 [[CMP]]
10061010
;
10071011
%fp = uitofp i64 %arg to double
10081012
%mul = fmul double -0.000000e+00, %fp

0 commit comments

Comments
 (0)