Check for all known bits on ret in InstCombine
authorHal Finkel <hfinkel@anl.gov>
Sun, 7 Sep 2014 21:28:34 +0000 (21:28 +0000)
committerHal Finkel <hfinkel@anl.gov>
Sun, 7 Sep 2014 21:28:34 +0000 (21:28 +0000)
From a combination of @llvm.assume calls (and perhaps through other means, such
as range metadata), it is possible that all bits of a return value might be
known. Previously, InstCombine did not check for this (which is understandable
given assumptions of constant propagation), but means that we'd miss simple
cases where assumptions are involved.

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

lib/Transforms/InstCombine/InstCombine.h
lib/Transforms/InstCombine/InstructionCombining.cpp
test/Transforms/InstCombine/assume.ll

index 0c3954f4c403b8c13ecfbcd9ddaf0a9e78e10211..6c0d4e74a7aa30288bef60bb7632bc4846c761af 100644 (file)
@@ -232,6 +232,7 @@ public:
   Instruction *visitStoreInst(StoreInst &SI);
   Instruction *visitBranchInst(BranchInst &BI);
   Instruction *visitSwitchInst(SwitchInst &SI);
+  Instruction *visitReturnInst(ReturnInst &RI);
   Instruction *visitInsertValueInst(InsertValueInst &IV);
   Instruction *visitInsertElementInst(InsertElementInst &IE);
   Instruction *visitExtractElementInst(ExtractElementInst &EI);
index e137f32db8b4d64336f053b841cf42fab9027cba..a8dd1c68288957554114f78db9d1804aad6adb37 100644 (file)
@@ -2004,7 +2004,25 @@ Instruction *InstCombiner::visitFree(CallInst &FI) {
   return nullptr;
 }
 
+Instruction *InstCombiner::visitReturnInst(ReturnInst &RI) {
+  if (RI.getNumOperands() == 0) // ret void
+    return nullptr;
+
+  Value *ResultOp = RI.getOperand(0);
+  Type *VTy = ResultOp->getType();
+  if (!VTy->isIntegerTy())
+    return nullptr;
 
+  // There might be assume intrinsics dominating this return that completely
+  // determine the value. If so, constant fold it.
+  unsigned BitWidth = VTy->getPrimitiveSizeInBits();
+  APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
+  computeKnownBits(ResultOp, KnownZero, KnownOne, 0, &RI);
+  if ((KnownZero|KnownOne).isAllOnesValue())
+    RI.setOperand(0, Constant::getIntegerValue(VTy, KnownOne));
+
+  return nullptr;
+}
 
 Instruction *InstCombiner::visitBranchInst(BranchInst &BI) {
   // Change br (not X), label True, label False to: br X, label False, True
index 286ca1e8d773eb1e5a1f45c8cc0ab35c40b233da..b328fb684aa7b7fa4b1d62fdd74810653a96e12a 100644 (file)
@@ -43,6 +43,18 @@ entry:
 ; Function Attrs: nounwind
 declare void @llvm.assume(i1) #1
 
+define i32 @simple(i32 %a) #1 {
+entry:
+
+; CHECK-LABEL: @simple
+; CHECK: call void @llvm.assume
+; CHECK: ret i32 4
+
+  %cmp = icmp eq i32 %a, 4
+  tail call void @llvm.assume(i1 %cmp)
+  ret i32 %a
+}
+
 ; Function Attrs: nounwind uwtable
 define i32 @can1(i1 %a, i1 %b, i1 %c) {
 entry: