switch (IID) {
default:
break;
+ case Intrinsic::canonicalize:
+ case Intrinsic::arithmetic_fence:
+ return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, Depth + 1);
case Intrinsic::maxnum: {
Value *V0 = I->getOperand(0), *V1 = I->getOperand(1);
auto isPositiveNum = [&](Value *V) {
}
declare float @llvm.fabs.f32(float)
+declare float @llvm.canonicalize.f32(float)
+declare float @llvm.arithmetic.fence.f32(float)
declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
declare float @llvm.sqrt.f32(float)
declare float @llvm.maxnum.f32(float, float)
%r = fsub double 0x7ff0000000000000, %x
ret double %r
}
+
+define i1 @canonicalize_known_positive(float %a) {
+; CHECK-LABEL: @canonicalize_known_positive(
+; CHECK-NEXT: ret i1 true
+;
+ %fabs = call float @llvm.fabs.f32(float %a)
+ %known.positive = call float @llvm.canonicalize.f32(float %fabs)
+ %cmp = fcmp nnan oge float %known.positive, 0.0
+ ret i1 %cmp
+}
+
+define i1 @canonicalize_unknown_positive(float %unknown) {
+; CHECK-LABEL: @canonicalize_unknown_positive(
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[UNKNOWN:%.*]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %cmp = fcmp nnan oge float %unknown, 0.0
+ ret i1 %cmp
+}
+
+define i1 @arithmetic_fence_known_positive(float %a) {
+; CHECK-LABEL: @arithmetic_fence_known_positive(
+; CHECK-NEXT: ret i1 true
+;
+ %fabs = call float @llvm.fabs.f32(float %a)
+ %known.positive = call float @llvm.arithmetic.fence.f32(float %fabs)
+ %cmp = fcmp nnan oge float %known.positive, 0.0
+ ret i1 %cmp
+}
+
+define i1 @arithmetic_fence_unknown_positive(float %unknown) {
+; CHECK-LABEL: @arithmetic_fence_unknown_positive(
+; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[UNKNOWN:%.*]])
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan oge float [[KNOWN_POSITIVE]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %known.positive = call float @llvm.arithmetic.fence.f32(float %unknown)
+ %cmp = fcmp nnan oge float %known.positive, 0.0
+ ret i1 %cmp
+}