[PATCH] D13222: [ValueTracking] teach computeKnownBits that a fabs() clears sign bits

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 28 12:19:34 PDT 2015


spatel created this revision.
spatel added reviewers: sanjoy, hfinkel, ab, majnemer.
spatel added a subscriber: llvm-commits.

This was requested in D13076: if we're going to canonicalize to fabs(), ValueTracking should know that fabs() clears sign bits.

In this patch (as in D13076), we're not handling vectors yet even though computeKnownBits' fabs() case itself should be vector-ready via the splat. Fixing this will require follow-on patches that correct logic that uses 'getScalarType'.

http://reviews.llvm.org/D13222

Files:
  lib/Analysis/ValueTracking.cpp
  test/Transforms/InstCombine/fabs.ll

Index: test/Transforms/InstCombine/fabs.ll
===================================================================
--- test/Transforms/InstCombine/fabs.ll
+++ test/Transforms/InstCombine/fabs.ll
@@ -41,6 +41,7 @@
 declare float @llvm.fabs.f32(float)
 declare double @llvm.fabs.f64(double)
 declare fp128 @llvm.fabs.f128(fp128)
+declare <4 x float> @llvm.fabs.v4f32(<4 x float>)
 
 define float @square_fabs_intrinsic_f32(float %x) {
   %mul = fmul float %x, %x
@@ -98,3 +99,27 @@
 ; CHECK-NEXT: ret float %sq
 }
 
+; A scalar fabs op makes the sign bit zero, so masking off all of the other bits means we can return zero.
+
+define i32 @fabs_value_tracking_f32(float %x) {
+  %call = call float @llvm.fabs.f32(float %x)
+  %bc = bitcast float %call to i32
+  %and = and i32 %bc, 2147483648
+  ret i32 %and
+
+; CHECK-LABEL: fabs_value_tracking_f32(
+; CHECK:       ret i32 0
+}
+
+; TODO: A vector fabs op makes the sign bits zero, so masking off all of the other bits means we can return zero.
+
+define <4 x i32> @fabs_value_tracking_v4f32(<4 x float> %x) {
+  %call = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
+  %bc = bitcast <4 x float> %call to <4 x i32>
+  %and = and <4 x i32> %bc, <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648>
+  ret <4 x i32> %and
+
+; CHECK-LABEL: fabs_value_tracking_v4f32(
+; CHECK:       ret <4 x i32> %and
+}
+
Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -1065,7 +1065,8 @@
   }
   case Instruction::BitCast: {
     Type *SrcTy = I->getOperand(0)->getType();
-    if ((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) &&
+    if ((SrcTy->isIntegerTy() || SrcTy->isPointerTy() ||
+         SrcTy->isFloatingPointTy()) &&
         // TODO: For now, not handling conversions like:
         // (bitcast i64 %x to <2 x i32>)
         !I->getType()->isVectorTy()) {
@@ -1372,6 +1373,12 @@
         KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - LowBits);
         break;
       }
+      case Intrinsic::fabs: {
+        Type *Ty = II->getType();
+        APInt SignBit = APInt::getSignBit(Ty->getScalarSizeInBits());
+        KnownZero |= APInt::getSplat(Ty->getPrimitiveSizeInBits(), SignBit);
+        break;
+      }
       case Intrinsic::x86_sse42_crc32_64_64:
         KnownZero |= APInt::getHighBitsSet(64, 32);
         break;
@@ -1431,8 +1438,9 @@
   unsigned BitWidth = KnownZero.getBitWidth();
 
   assert((V->getType()->isIntOrIntVectorTy() ||
+          V->getType()->isFPOrFPVectorTy() ||
           V->getType()->getScalarType()->isPointerTy()) &&
-         "Not integer or pointer type!");
+         "Not integer, floating point, or pointer type!");
   assert((DL.getTypeSizeInBits(V->getType()->getScalarType()) == BitWidth) &&
          (!V->getType()->isIntOrIntVectorTy() ||
           V->getType()->getScalarSizeInBits() == BitWidth) &&


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13222.35897.patch
Type: text/x-patch
Size: 2948 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150928/5fa518cf/attachment.bin>


More information about the llvm-commits mailing list