[llvm] 8eb2f86 - [CodeGenPrepare] Fold br(freeze(icmp x, const)) to br(icmp(freeze x, const))
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 11 12:49:10 PDT 2020
The title on this should have been updated before submission as the
requirement for a branch was relaxed. Here's a more appropriate title.
[CodeGenPrepare] Fold freeze(icmp x, const) to icmp(freeze x, const)
On 3/11/20 11:16 AM, Juneyoung Lee via llvm-commits wrote:
> Author: Juneyoung Lee
> Date: 2020-03-12T03:16:15+09:00
> New Revision: 8eb2f865c3034934231b1fb3471960191a6f754f
>
> URL: https://github.com/llvm/llvm-project/commit/8eb2f865c3034934231b1fb3471960191a6f754f
> DIFF: https://github.com/llvm/llvm-project/commit/8eb2f865c3034934231b1fb3471960191a6f754f.diff
>
> LOG: [CodeGenPrepare] Fold br(freeze(icmp x, const)) to br(icmp(freeze x, const))
>
> Summary:
> This patch helps CodeGenPrepare move freeze into the icmp when it is used by branch.
> It reenables generation of efficient conditional jumps.
>
> This is only done when at least one of icmp's operands is constant to prevent the transformation from increasing # of freeze instructions.
>
> Performance degradation of MultiSource/Benchmarks/Ptrdist/yacr2/yacr2.test is resolved with this patch.
>
> Checked with Alive2
>
> Reviewers: reames, fhahn, nlopes
>
> Reviewed By: reames
>
> Subscribers: jdoerfert, hiraditya, llvm-commits
>
> Tags: #llvm
>
> Differential Revision: https://reviews.llvm.org/D75859
>
> Added:
> llvm/test/Transforms/CodeGenPrepare/X86/freeze-icmp.ll
>
> Modified:
> llvm/lib/CodeGen/CodeGenPrepare.cpp
>
> Removed:
>
>
>
> ################################################################################
> diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
> index 052316f34bb6..262036499b30 100644
> --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
> +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
> @@ -7191,6 +7191,26 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, bool &ModifiedDT) {
> return false;
> }
>
> + if (FreezeInst *FI = dyn_cast<FreezeInst>(I)) {
> + // br(freeze(icmp a, const)) -> br(icmp (freeze a), const)
> + // This helps generate efficient conditional jumps.
> + if (ICmpInst *II = dyn_cast<ICmpInst>(FI->getOperand(0))) {
> + auto Op0 = II->getOperand(0), Op1 = II->getOperand(1);
> + bool Const0 = isa<ConstantInt>(Op0), Const1 = isa<ConstantInt>(Op1);
> + if (II->hasOneUse() && (Const0 || Const1)) {
> + if (!Const0 || !Const1) {
> + auto *F = new FreezeInst(Const0 ? Op1 : Op0, "", II);
> + F->takeName(FI);
> + II->setOperand(Const0 ? 1 : 0, F);
> + }
> + FI->replaceAllUsesWith(II);
> + FI->eraseFromParent();
> + return true;
> + }
> + }
> + return false;
> + }
> +
> if (tryToSinkFreeOperands(I))
> return true;
>
>
> diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/freeze-icmp.ll b/llvm/test/Transforms/CodeGenPrepare/X86/freeze-icmp.ll
> new file mode 100644
> index 000000000000..e4febc15c03e
> --- /dev/null
> +++ b/llvm/test/Transforms/CodeGenPrepare/X86/freeze-icmp.ll
> @@ -0,0 +1,75 @@
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> +; RUN: opt -S -codegenprepare < %s | FileCheck %s
> +
> +target triple = "x86_64-unknown-linux-gnu"
> +
> +define void @f1(i32 %a) {
> +; CHECK-LABEL: @f1(
> +; CHECK-NEXT: [[FR1:%.*]] = freeze i32 [[A:%.*]]
> +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[FR1]], 0
> +; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
> +; CHECK: A:
> +; CHECK-NEXT: call void @g1()
> +; CHECK-NEXT: ret void
> +; CHECK: B:
> +; CHECK-NEXT: call void @g2()
> +; CHECK-NEXT: ret void
> +;
> + %c = icmp eq i32 %a, 0
> + %fr = freeze i1 %c
> + br i1 %fr, label %A, label %B
> +A:
> + call void @g1()
> + ret void
> +B:
> + call void @g2()
> + ret void
> +}
> +
> +define void @f2(i32 %a) {
> +; CHECK-LABEL: @f2(
> +; CHECK-NEXT: [[FR1:%.*]] = freeze i32 [[A:%.*]]
> +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 0, [[FR1]]
> +; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
> +; CHECK: A:
> +; CHECK-NEXT: call void @g1()
> +; CHECK-NEXT: ret void
> +; CHECK: B:
> +; CHECK-NEXT: call void @g2()
> +; CHECK-NEXT: ret void
> +;
> + %c = icmp eq i32 0, %a
> + %fr = freeze i1 %c
> + br i1 %fr, label %A, label %B
> +A:
> + call void @g1()
> + ret void
> +B:
> + call void @g2()
> + ret void
> +}
> +
> +define void @f3(i32 %a) {
> +; CHECK-LABEL: @f3(
> +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 0, 1
> +; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
> +; CHECK: A:
> +; CHECK-NEXT: call void @g1()
> +; CHECK-NEXT: ret void
> +; CHECK: B:
> +; CHECK-NEXT: call void @g2()
> +; CHECK-NEXT: ret void
> +;
> + %c = icmp eq i32 0, 1
> + %fr = freeze i1 %c
> + br i1 %fr, label %A, label %B
> +A:
> + call void @g1()
> + ret void
> +B:
> + call void @g2()
> + ret void
> +}
> +
> +declare void @g1()
> +declare void @g2()
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list