ValueTracking: Teach CannotBeOrderedLessThanZero about trivial ops
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Sun, 4 Dec 2022 03:49:47 +0000 (22:49 -0500)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Mon, 5 Dec 2022 13:39:07 +0000 (08:39 -0500)
Handle canonicalize and arithmetic.fence

llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll

index e86e9d1..0e4ca6a 100644 (file)
@@ -3653,6 +3653,9 @@ static bool cannotBeOrderedLessThanZeroImpl(const Value *V,
     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) {
index 3529da6..0c0f7b6 100644 (file)
@@ -277,6 +277,8 @@ define float @PR22688(float %x) {
 }
 
 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)
@@ -913,3 +915,43 @@ define double @fsub_inf_op0(double %x) {
   %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
+}