summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2015-10-08 16:56:55 +0000
committerSanjay Patel <spatel@rotateright.com>2015-10-08 16:56:55 +0000
commit9115cf8c9dc23e3a9bd0e915f426b4fc694cd133 (patch)
tree08fe8f3380b4e09941e8696311d7747fb03c8d93
parentaac75382160bb19e7d58c8d3af15ee629eaa860d (diff)
downloadbcm5719-llvm-9115cf8c9dc23e3a9bd0e915f426b4fc694cd133.tar.gz
bcm5719-llvm-9115cf8c9dc23e3a9bd0e915f426b4fc694cd133.zip
[ValueTracking] teach computeKnownBits that a fabs() clears sign bits
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 in this patch. Fixing this will require follow-on patches to correct other logic that uses 'getScalarType'. Differential Revision: http://reviews.llvm.org/D13222 llvm-svn: 249701
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp12
-rw-r--r--llvm/test/Transforms/InstCombine/fabs.ll25
2 files changed, 35 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index d8a449193a3..2259d871c8c 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1065,7 +1065,8 @@ static void computeKnownBitsFromOperator(Operator *I, APInt &KnownZero,
}
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()) {
@@ -1378,6 +1379,12 @@ static void computeKnownBitsFromOperator(Operator *I, APInt &KnownZero,
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;
@@ -1477,8 +1484,9 @@ void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
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) &&
diff --git a/llvm/test/Transforms/InstCombine/fabs.ll b/llvm/test/Transforms/InstCombine/fabs.ll
index 0479549bea3..941270df0e9 100644
--- a/llvm/test/Transforms/InstCombine/fabs.ll
+++ b/llvm/test/Transforms/InstCombine/fabs.ll
@@ -41,6 +41,7 @@ define fp128 @square_fabs_call_f128(fp128 %x) {
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 @@ define float @square_fabs_shrink_call2(float %x) {
; 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
+}
+
OpenPOWER on IntegriCloud