[llvm] r174650 - Identify and simplify idempotent intrinsics. Testcase included.

Nuno Lopes nunoplopes at sapo.pt
Thu Feb 7 11:58:15 PST 2013


Wait, aren't all nounwind + readnone functions idempotent?
Nuno

----- Original Message -----
> Author: milseman
> Date: Thu Feb  7 13:26:05 2013
> New Revision: 174650
>
> URL: http://llvm.org/viewvc/llvm-project?rev=174650&view=rev
> Log:
> Identify and simplify idempotent intrinsics. Test case included.
>
> Modified:
>    llvm/trunk/lib/Analysis/InstructionSimplify.cpp
>    llvm/trunk/test/Transforms/InstSimplify/call.ll
>
> Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=174650&r1=174649&r2=174650&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
> +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Thu Feb  7 13:26:05 
> 2013
> @@ -2925,6 +2925,37 @@ Value *llvm::SimplifyCmpInst(unsigned Pr
>                            RecursionLimit);
> }
>
> +static bool IsIdempotent(Intrinsic::ID ID) {
> +  switch (ID) {
> +  default: return false;
> +
> +  // Unary idempotent: f(f(x)) = f(x)
> +  case Intrinsic::fabs:
> +  case Intrinsic::floor:
> +  case Intrinsic::ceil:
> +  case Intrinsic::trunc:
> +  case Intrinsic::rint:
> +  case Intrinsic::nearbyint:
> +    return true;
> +  }
> +}
> +
> +template <typename IterTy>
> +static Value *SimplifyIntrinsic(Intrinsic::ID IID, IterTy ArgBegin, 
> IterTy ArgEnd,
> +                                const Query &Q, unsigned MaxRecurse) {
> +  // Perform idempotent optimizations
> +  if (!IsIdempotent(IID))
> +    return 0;
> +
> +  // Unary Ops
> +  if (std::distance(ArgBegin, ArgEnd) == 1)
> +    if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(*ArgBegin))
> +      if (II->getIntrinsicID() == IID)
> +        return II;
> +
> +  return 0;
> +}
> +
> template <typename IterTy>
> static Value *SimplifyCall(Value *V, IterTy ArgBegin, IterTy ArgEnd,
>                            const Query &Q, unsigned MaxRecurse) {
> @@ -2941,6 +2972,11 @@ static Value *SimplifyCall(Value *V, Ite
>   if (!F)
>     return 0;
>
> +  if (unsigned IID = F->getIntrinsicID())
> +    if (Value *Ret =
> +        SimplifyIntrinsic((Intrinsic::ID) IID, ArgBegin, ArgEnd, Q, 
> MaxRecurse))
> +      return Ret;
> +
>   if (!canConstantFoldCallTo(F))
>     return 0;
>
>
> Modified: llvm/trunk/test/Transforms/InstSimplify/call.ll
> URL: 
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/call.ll?rev=174650&r1=174649&r2=174650&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstSimplify/call.ll (original)
> +++ llvm/trunk/test/Transforms/InstSimplify/call.ll Thu Feb  7 13:26:05 
> 2013
> @@ -50,3 +50,54 @@ define float @test_fabs_libcall() {
>   ret float %x
> ; CHECK-NEXT: ret float 4.2{{0+}}e+01
> }
> +
> +
> +declare float @llvm.fabs.f32(float) nounwind readnone
> +declare float @llvm.floor.f32(float) nounwind readnone
> +declare float @llvm.ceil.f32(float) nounwind readnone
> +declare float @llvm.trunc.f32(float) nounwind readnone
> +declare float @llvm.rint.f32(float) nounwind readnone
> +declare float @llvm.nearbyint.f32(float) nounwind readnone
> +
> +; Test idempotent intrinsics
> +define float @test_idempotence(float %a) {
> +; CHECK: @test_idempotence
> +
> +; CHECK: fabs
> +; CHECK-NOT: fabs
> +  %a0 = call float @llvm.fabs.f32(float %a)
> +  %a1 = call float @llvm.fabs.f32(float %a0)
> +
> +; CHECK: floor
> +; CHECK-NOT: floor
> +  %b0 = call float @llvm.floor.f32(float %a)
> +  %b1 = call float @llvm.floor.f32(float %b0)
> +
> +; CHECK: ceil
> +; CHECK-NOT: ceil
> +  %c0 = call float @llvm.ceil.f32(float %a)
> +  %c1 = call float @llvm.ceil.f32(float %c0)
> +
> +; CHECK: trunc
> +; CHECK-NOT: trunc
> +  %d0 = call float @llvm.trunc.f32(float %a)
> +  %d1 = call float @llvm.trunc.f32(float %d0)
> +
> +; CHECK: rint
> +; CHECK-NOT: rint
> +  %e0 = call float @llvm.rint.f32(float %a)
> +  %e1 = call float @llvm.rint.f32(float %e0)
> +
> +; CHECK: nearbyint
> +; CHECK-NOT: nearbyint
> +  %f0 = call float @llvm.nearbyint.f32(float %a)
> +  %f1 = call float @llvm.nearbyint.f32(float %f0)
> +
> +  %r0 = fadd float %a1, %b1
> +  %r1 = fadd float %r0, %c1
> +  %r2 = fadd float %r1, %d1
> +  %r3 = fadd float %r2, %e1
> +  %r4 = fadd float %r3, %f1
> +
> +  ret float %r4
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits 




More information about the llvm-commits mailing list