Skip to content

Commit aa25c92

Browse files
committed
[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 #58046. Differential Revision: https://reviews.llvm.org/D134876
1 parent 8b38a2c commit aa25c92

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3629,14 +3629,23 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
36293629
// Unsigned integers are always nonnegative.
36303630
case Instruction::UIToFP:
36313631
return true;
3632-
case Instruction::FMul:
36333632
case Instruction::FDiv:
3634-
// X * X is always non-negative or a NaN.
36353633
// X / X is always exactly 1.0 or a NaN.
36363634
if (I->getOperand(0) == I->getOperand(1) &&
36373635
(!SignBitOnly || cast<FPMathOperator>(I)->hasNoNaNs()))
36383636
return true;
36393637

3638+
// Set SignBitOnly for RHS, because X / -0.0 is -Inf (or NaN).
3639+
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly,
3640+
Depth + 1) &&
3641+
cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI,
3642+
/*SignBitOnly*/ true, Depth + 1);
3643+
case Instruction::FMul:
3644+
// X * X is always non-negative or a NaN.
3645+
if (I->getOperand(0) == I->getOperand(1) &&
3646+
(!SignBitOnly || cast<FPMathOperator>(I)->hasNoNaNs()))
3647+
return true;
3648+
36403649
[[fallthrough]];
36413650
case Instruction::FAdd:
36423651
case Instruction::FRem:

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

Lines changed: 6 additions & 2 deletions
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)