Skip to content

Commit 42fcda0

Browse files
nikicveselypeta
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
2 parents b0f5d19 + aa25c92 commit 42fcda0

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
@@ -3762,14 +3762,23 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
37623762
// Unsigned integers are always nonnegative.
37633763
case Instruction::UIToFP:
37643764
return true;
3765-
case Instruction::FMul:
37663765
case Instruction::FDiv:
3767-
// X * X is always non-negative or a NaN.
37683766
// X / X is always exactly 1.0 or a NaN.
37693767
if (I->getOperand(0) == I->getOperand(1) &&
37703768
(!SignBitOnly || cast<FPMathOperator>(I)->hasNoNaNs()))
37713769
return true;
37723770

3771+
// Set SignBitOnly for RHS, because X / -0.0 is -Inf (or NaN).
3772+
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly,
3773+
Depth + 1) &&
3774+
cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI,
3775+
/*SignBitOnly*/ true, Depth + 1);
3776+
case Instruction::FMul:
3777+
// X * X is always non-negative or a NaN.
3778+
if (I->getOperand(0) == I->getOperand(1) &&
3779+
(!SignBitOnly || cast<FPMathOperator>(I)->hasNoNaNs()))
3780+
return true;
3781+
37733782
[[fallthrough]];
37743783
case Instruction::FAdd:
37753784
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)