[llvm-commits] [llvm] r171194 - in /llvm/trunk: include/llvm/Analysis/InstructionSimplify.h lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/call.ll

Chandler Carruth chandlerc at gmail.com
Fri Dec 28 06:23:30 PST 2012


Author: chandlerc
Date: Fri Dec 28 08:23:29 2012
New Revision: 171194

URL: http://llvm.org/viewvc/llvm-project?rev=171194&view=rev
Log:
Teach instsimplify to use the constant folder where appropriate for
constant folding calls. Add the initial tests for this which show that
now instsimplify can simplify blindingly obvious code patterns expressed
with both intrinsics and library calls.

Added:
    llvm/trunk/test/Transforms/InstSimplify/call.ll
Modified:
    llvm/trunk/include/llvm/Analysis/InstructionSimplify.h
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp

Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=171194&r1=171193&r2=171194&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (original)
+++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Fri Dec 28 08:23:29 2012
@@ -211,7 +211,7 @@
   /// the result.
   ///
   /// If this call could not be simplified returns null.
-  Value *SimplifyCall(Value *F, User::op_iterator ArgBegin,
+  Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
                       User::op_iterator ArgEnd, const DataLayout *TD = 0,
                       const TargetLibraryInfo *TLI = 0,
                       const DominatorTree *DT = 0);
@@ -220,7 +220,7 @@
   /// result.
   ///
   /// If this call could not be simplified returns null.
-  Value *SimplifyCall(Value *F, ArrayRef<Value *> Args,
+  Value *SimplifyCall(Value *V, ArrayRef<Value *> Args,
                       const DataLayout *TD = 0,
                       const TargetLibraryInfo *TLI = 0,
                       const DominatorTree *DT = 0);

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=171194&r1=171193&r2=171194&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Fri Dec 28 08:23:29 2012
@@ -2870,32 +2870,53 @@
 }
 
 template <typename IterTy>
-static Value *SimplifyCall(Value *F, IterTy ArgBegin, IterTy ArgEnd,
+static Value *SimplifyIntrinsic(Intrinsic::ID IID, IterTy ArgBegin, IterTy ArgEnd,
+                                const Query &Q, unsigned MaxRecurse) {
+}
+
+template <typename IterTy>
+static Value *SimplifyCall(Value *V, IterTy ArgBegin, IterTy ArgEnd,
                            const Query &Q, unsigned MaxRecurse) {
-  Type *Ty = F->getType();
+  Type *Ty = V->getType();
   if (PointerType *PTy = dyn_cast<PointerType>(Ty))
     Ty = PTy->getElementType();
   FunctionType *FTy = cast<FunctionType>(Ty);
 
   // call undef -> undef
-  if (isa<UndefValue>(F))
+  if (isa<UndefValue>(V))
     return UndefValue::get(FTy->getReturnType());
 
-  return 0;
+  Function *F = dyn_cast<Function>(V);
+  if (!F)
+    return 0;
+
+  if (!canConstantFoldCallTo(F))
+    return 0;
+
+  SmallVector<Constant *, 4> ConstantArgs;
+  ConstantArgs.reserve(ArgEnd - ArgBegin);
+  for (IterTy I = ArgBegin, E = ArgEnd; I != E; ++I) {
+    Constant *C = dyn_cast<Constant>(*I);
+    if (!C)
+      return 0;
+    ConstantArgs.push_back(C);
+  }
+
+  return ConstantFoldCall(F, ConstantArgs, Q.TLI);
 }
 
-Value *llvm::SimplifyCall(Value *F, User::op_iterator ArgBegin,
+Value *llvm::SimplifyCall(Value *V, User::op_iterator ArgBegin,
                           User::op_iterator ArgEnd, const DataLayout *TD,
                           const TargetLibraryInfo *TLI,
                           const DominatorTree *DT) {
-  return ::SimplifyCall(F, ArgBegin, ArgEnd, Query(TD, TLI, DT),
+  return ::SimplifyCall(V, ArgBegin, ArgEnd, Query(TD, TLI, DT),
                         RecursionLimit);
 }
 
-Value *llvm::SimplifyCall(Value *F, ArrayRef<Value *> Args,
+Value *llvm::SimplifyCall(Value *V, ArrayRef<Value *> Args,
                           const DataLayout *TD, const TargetLibraryInfo *TLI,
                           const DominatorTree *DT) {
-  return ::SimplifyCall(F, Args.begin(), Args.end(), Query(TD, TLI, DT),
+  return ::SimplifyCall(V, Args.begin(), Args.end(), Query(TD, TLI, DT),
                         RecursionLimit);
 }
 

Added: llvm/trunk/test/Transforms/InstSimplify/call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/call.ll?rev=171194&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/call.ll (added)
+++ llvm/trunk/test/Transforms/InstSimplify/call.ll Fri Dec 28 08:23:29 2012
@@ -0,0 +1,52 @@
+; RUN: opt < %s -instsimplify -S | FileCheck %s
+
+declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)
+
+define i1 @test_uadd1() {
+; CHECK: @test_uadd1
+  %x = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 254, i8 3)
+  %overflow = extractvalue {i8, i1} %x, 1
+  ret i1 %overflow
+; CHECK-NEXT: ret i1 true
+}
+
+define i8 @test_uadd2() {
+; CHECK: @test_uadd2
+  %x = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 254, i8 44)
+  %result = extractvalue {i8, i1} %x, 0
+  ret i8 %result
+; CHECK-NEXT: ret i8 42
+}
+
+declare i256 @llvm.cttz.i256(i256 %src, i1 %is_zero_undef)
+
+define i256 @test_cttz() {
+; CHECK: @test_cttz
+  %x = call i256 @llvm.cttz.i256(i256 10, i1 false)
+  ret i256 %x
+; CHECK-NEXT: ret i256 1
+}
+
+declare i256 @llvm.ctpop.i256(i256 %src)
+
+define i256 @test_ctpop() {
+; CHECK: @test_ctpop
+  %x = call i256 @llvm.ctpop.i256(i256 10)
+  ret i256 %x
+; CHECK-NEXT: ret i256 2
+}
+
+; Test a non-intrinsic that we know about as a library call.
+declare float @fabs(float %x)
+
+define float @test_fabs_libcall() {
+; CHECK: @test_fabs_libcall
+
+  %x = call float @fabs(float -42.0)
+; This is still a real function call, so instsimplify won't nuke it -- other
+; passes have to do that.
+; CHECK-NEXT: call float @fabs
+
+  ret float %x
+; CHECK-NEXT: ret float 4.2{{0+}}e+01
+}





More information about the llvm-commits mailing list