]> granicus.if.org Git - llvm/commitdiff
Teach computeKnownBits to look through returned-argument functions
authorHal Finkel <hfinkel@anl.gov>
Mon, 11 Jul 2016 02:25:14 +0000 (02:25 +0000)
committerHal Finkel <hfinkel@anl.gov>
Mon, 11 Jul 2016 02:25:14 +0000 (02:25 +0000)
If a function is known to return one of its arguments, we can use that in order
to compute known bits of the return value.

Differential Revision: http://reviews.llvm.org/D9397

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275036 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ValueTracking.cpp
test/Transforms/InstCombine/align-attr.ll

index 5c5d213e73dad0e6c71c7c45b382c27c3bf47097..3277c3c47b83175e1fd2c8a5ed7c1f1096ae6660 100644 (file)
@@ -1279,11 +1279,16 @@ static void computeKnownBitsFromOperator(Operator *I, APInt &KnownZero,
   }
   case Instruction::Call:
   case Instruction::Invoke:
+    // If range metadata is attached to this call, set known bits from that,
+    // and then intersect with known bits based on other properties of the
+    // function.
     if (MDNode *MD = cast<Instruction>(I)->getMetadata(LLVMContext::MD_range))
       computeKnownBitsFromRangeMetadata(*MD, KnownZero, KnownOne);
-    // If a range metadata is attached to this IntrinsicInst, intersect the
-    // explicit range specified by the metadata and the implicit range of
-    // the intrinsic.
+    if (Value *RV = CallSite(I).getReturnedArgOperand()) {
+      computeKnownBits(RV, KnownZero2, KnownOne2, Depth + 1, Q);
+      KnownZero |= KnownZero2;
+      KnownOne |= KnownOne2;
+    }
     if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
       switch (II->getIntrinsicID()) {
       default: break;
index 99a17db13c4c64e9c54cc5d94d66ff1bde8d035e..75a3766b7d1f81a314e6b37e1021f5479e74a43d 100644 (file)
@@ -13,3 +13,16 @@ entry:
 ; CHECK: ret i32
 }
 
+define i32 @foo2(i32* align 32 %a) #0 {
+entry:
+  %v = call i32* @func1(i32* %a)
+  %0 = load i32, i32* %v, align 4
+  ret i32 %0
+
+; CHECK-LABEL: @foo2
+; CHECK-DAG: load i32, i32* %v, align 32
+; CHECK: ret i32
+}
+
+declare i32* @func1(i32* returned) nounwind
+