[PATCH] Check for all known bits on ret in InstCombine

hfinkel at anl.gov hfinkel at anl.gov
Thu Jul 17 10:58:40 PDT 2014


Hi chandlerc,

>From a combination of invariants (and perhaps through other means), it is possible that all bits of a return value might be known. Currently, InstCombine does not check for this (which is understandable given assumptions of constant propagation), but means that we'd miss simple cases where invariants are involved.

http://reviews.llvm.org/D4567

Files:
  lib/Transforms/InstCombine/InstCombine.h
  lib/Transforms/InstCombine/InstructionCombining.cpp
  test/Transforms/InstCombine/invariants.ll

Index: lib/Transforms/InstCombine/InstCombine.h
===================================================================
--- lib/Transforms/InstCombine/InstCombine.h
+++ lib/Transforms/InstCombine/InstCombine.h
@@ -217,6 +217,7 @@
   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: lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- lib/Transforms/InstCombine/InstructionCombining.cpp
+++ lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1923,7 +1923,25 @@
   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 invariants 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: test/Transforms/InstCombine/invariants.ll
===================================================================
--- test/Transforms/InstCombine/invariants.ll
+++ test/Transforms/InstCombine/invariants.ll
@@ -43,6 +43,18 @@
 ; Function Attrs: nounwind
 declare void @llvm.invariant(i1) #1
 
+define i32 @simple(i32 %a) #1 {
+entry:
+
+; CHECK-LABEL: @simple
+; CHECK: call void @llvm.invariant
+; CHECK: ret i32 4
+
+  %cmp = icmp eq i32 %a, 4
+  tail call void @llvm.invariant(i1 %cmp)
+  ret i32 %a
+}
+
 ; Function Attrs: nounwind uwtable
 define i32 @bar1(i32 %a) #0 {
 entry:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4567.11597.patch
Type: text/x-patch
Size: 2303 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140717/508177cf/attachment.bin>


More information about the llvm-commits mailing list