[llvm] c663b8c - ValueTracking: Teach CannotBeOrderedLessThanZero about rounding intrinsics
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 15 06:44:51 PST 2023
Author: Matt Arsenault
Date: 2023-01-15T09:44:45-05:00
New Revision: c663b8c4295e70ccfde9a88cb22d0d0b42d5288f
URL: https://github.com/llvm/llvm-project/commit/c663b8c4295e70ccfde9a88cb22d0d0b42d5288f
DIFF: https://github.com/llvm/llvm-project/commit/c663b8c4295e70ccfde9a88cb22d0d0b42d5288f.diff
LOG: ValueTracking: Teach CannotBeOrderedLessThanZero about rounding intrinsics
These should obviously preserve the sign although the variety of these
always confuses me.
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index f2a63e7294db..7c38c6087f3c 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3668,6 +3668,14 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
break;
case Intrinsic::canonicalize:
case Intrinsic::arithmetic_fence:
+ case Intrinsic::floor:
+ case Intrinsic::ceil:
+ case Intrinsic::trunc:
+ case Intrinsic::rint:
+ case Intrinsic::nearbyint:
+ case Intrinsic::round:
+ case Intrinsic::roundeven:
+ case Intrinsic::fptrunc_round:
return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, Depth + 1);
case Intrinsic::maxnum: {
Value *V0 = I->getOperand(0), *V1 = I->getOperand(1);
diff --git a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
index a2aac2d723d9..4e75959832b3 100644
--- a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
+++ b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
@@ -277,7 +277,16 @@ define float @PR22688(float %x) {
}
declare float @llvm.fabs.f32(float)
+declare double @llvm.fabs.f64(double)
declare float @llvm.canonicalize.f32(float)
+declare float @llvm.floor.f32(float)
+declare float @llvm.ceil.f32(float)
+declare float @llvm.trunc.f32(float)
+declare float @llvm.rint.f32(float)
+declare float @llvm.nearbyint.f32(float)
+declare float @llvm.round.f32(float)
+declare float @llvm.roundeven.f32(float)
+declare float @llvm.fptrunc.round.f32.f64(double, metadata)
declare float @llvm.arithmetic.fence.f32(float)
declare float @llvm.copysign.f32(float, float)
declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
@@ -990,3 +999,179 @@ define i1 @copysign_unknown_positive(float %unknown, float %unknown.sign) {
%cmp = fcmp nnan oge float %copysign, 0.0
ret i1 %cmp
}
+
+; https://alive2.llvm.org/ce/z/Y-EyY3
+define i1 @floor_known_positive(float %a) {
+; CHECK-LABEL: @floor_known_positive(
+; CHECK-NEXT: ret i1 true
+;
+ %fabs = call float @llvm.fabs.f32(float %a)
+ %known.positive = call float @llvm.floor.f32(float %fabs)
+ %cmp = fcmp nnan oge float %known.positive, 0.0
+ ret i1 %cmp
+}
+
+define i1 @floor_unknown_positive(float %unknown) {
+; CHECK-LABEL: @floor_unknown_positive(
+; CHECK-NEXT: [[OP:%.*]] = call float @llvm.floor.f32(float [[UNKNOWN:%.*]])
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %op = call float @llvm.floor.f32(float %unknown)
+ %cmp = fcmp nnan oge float %op, 0.0
+ ret i1 %cmp
+}
+
+; https://alive2.llvm.org/ce/z/3tBUoW
+define i1 @ceil_known_positive(float %a) {
+; CHECK-LABEL: @ceil_known_positive(
+; CHECK-NEXT: ret i1 true
+;
+ %fabs = call float @llvm.fabs.f32(float %a)
+ %known.positive = call float @llvm.ceil.f32(float %fabs)
+ %cmp = fcmp nnan oge float %known.positive, 0.0
+ ret i1 %cmp
+}
+
+define i1 @ceil_unknown_positive(float %unknown) {
+; CHECK-LABEL: @ceil_unknown_positive(
+; CHECK-NEXT: [[OP:%.*]] = call float @llvm.ceil.f32(float [[UNKNOWN:%.*]])
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+
+ %op = call float @llvm.ceil.f32(float %unknown)
+ %cmp = fcmp nnan oge float %op, 0.0
+ ret i1 %cmp
+}
+
+; https://alive2.llvm.org/ce/z/RbyJPX
+define i1 @trunc_known_positive(float %a) {
+; CHECK-LABEL: @trunc_known_positive(
+; CHECK-NEXT: ret i1 true
+;
+ %fabs = call float @llvm.fabs.f32(float %a)
+ %known.positive = call float @llvm.trunc.f32(float %fabs)
+ %cmp = fcmp nnan oge float %known.positive, 0.0
+ ret i1 %cmp
+}
+
+define i1 @trunc_unknown_positive(float %unknown) {
+; CHECK-LABEL: @trunc_unknown_positive(
+; CHECK-NEXT: [[OP:%.*]] = call float @llvm.trunc.f32(float [[UNKNOWN:%.*]])
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %op = call float @llvm.trunc.f32(float %unknown)
+ %cmp = fcmp nnan oge float %op, 0.0
+ ret i1 %cmp
+}
+
+; https://alive2.llvm.org/ce/z/bjC2Jm
+define i1 @rint_known_positive(float %a) {
+; CHECK-LABEL: @rint_known_positive(
+; CHECK-NEXT: ret i1 true
+;
+ %fabs = call float @llvm.fabs.f32(float %a)
+ %known.positive = call float @llvm.rint.f32(float %fabs)
+ %cmp = fcmp nnan oge float %known.positive, 0.0
+ ret i1 %cmp
+}
+
+define i1 @rint_unknown_positive(float %unknown) {
+; CHECK-LABEL: @rint_unknown_positive(
+; CHECK-NEXT: [[OP:%.*]] = call float @llvm.rint.f32(float [[UNKNOWN:%.*]])
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %op = call float @llvm.rint.f32(float %unknown)
+ %cmp = fcmp nnan oge float %op, 0.0
+ ret i1 %cmp
+}
+
+; https://alive2.llvm.org/ce/z/dFiL9n
+define i1 @nearbyint_known_positive(float %a) {
+; CHECK-LABEL: @nearbyint_known_positive(
+; CHECK-NEXT: ret i1 true
+;
+ %fabs = call float @llvm.fabs.f32(float %a)
+ %known.positive = call float @llvm.nearbyint.f32(float %fabs)
+ %cmp = fcmp nnan oge float %known.positive, 0.0
+ ret i1 %cmp
+}
+
+define i1 @nearbyint_unknown_positive(float %unknown) {
+; CHECK-LABEL: @nearbyint_unknown_positive(
+; CHECK-NEXT: [[OP:%.*]] = call float @llvm.nearbyint.f32(float [[UNKNOWN:%.*]])
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %op = call float @llvm.nearbyint.f32(float %unknown)
+ %cmp = fcmp nnan oge float %op, 0.0
+ ret i1 %cmp
+}
+
+; https://alive2.llvm.org/ce/z/kPhS-d
+define i1 @round_known_positive(float %a) {
+; CHECK-LABEL: @round_known_positive(
+; CHECK-NEXT: ret i1 true
+;
+ %fabs = call float @llvm.fabs.f32(float %a)
+ %known.positive = call float @llvm.round.f32(float %fabs)
+ %cmp = fcmp nnan oge float %known.positive, 0.0
+ ret i1 %cmp
+}
+
+define i1 @round_unknown_positive(float %unknown) {
+; CHECK-LABEL: @round_unknown_positive(
+; CHECK-NEXT: [[OP:%.*]] = call float @llvm.round.f32(float [[UNKNOWN:%.*]])
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %op = call float @llvm.round.f32(float %unknown)
+ %cmp = fcmp nnan oge float %op, 0.0
+ ret i1 %cmp
+}
+
+; https://alive2.llvm.org/ce/z/Z_tfsu
+define i1 @roundeven_known_positive(float %a) {
+; CHECK-LABEL: @roundeven_known_positive(
+; CHECK-NEXT: ret i1 true
+;
+ %fabs = call float @llvm.fabs.f32(float %a)
+ %known.positive = call float @llvm.roundeven.f32(float %fabs)
+ %cmp = fcmp nnan oge float %known.positive, 0.0
+ ret i1 %cmp
+}
+
+define i1 @roundeven_unknown_positive(float %unknown) {
+; CHECK-LABEL: @roundeven_unknown_positive(
+; CHECK-NEXT: [[OP:%.*]] = call float @llvm.roundeven.f32(float [[UNKNOWN:%.*]])
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %op = call float @llvm.roundeven.f32(float %unknown)
+ %cmp = fcmp nnan oge float %op, 0.0
+ ret i1 %cmp
+}
+
+define i1 @fptrunc_round_known_positive(double %a) {
+; CHECK-LABEL: @fptrunc_round_known_positive(
+; CHECK-NEXT: ret i1 true
+;
+ %fabs = call double @llvm.fabs.f64(double %a)
+ %known.positive = call float @llvm.fptrunc.round.f32.f64(double %fabs, metadata !"round.downward")
+ %cmp = fcmp nnan oge float %known.positive, 0.0
+ ret i1 %cmp
+}
+
+define i1 @fptrunc_round_unknown_positive(double %unknown) {
+; CHECK-LABEL: @fptrunc_round_unknown_positive(
+; CHECK-NEXT: [[OP:%.*]] = call float @llvm.fptrunc.round.f32.f64(double [[UNKNOWN:%.*]], metadata !"round.downward")
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[OP]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %op = call float @llvm.fptrunc.round.f32.f64(double %unknown, metadata !"round.downward")
+ %cmp = fcmp nnan oge float %op, 0.0
+ ret i1 %cmp
+}
More information about the llvm-commits
mailing list