diff options
author | John Brawn <john.brawn@arm.com> | 2017-06-28 14:11:15 +0000 |
---|---|---|
committer | John Brawn <john.brawn@arm.com> | 2017-06-28 14:11:15 +0000 |
commit | 5ae42c7d63acab17352921404d3e9c35f38829d3 (patch) | |
tree | 78d9c8d3518c72434cef541a6abb875febe72d54 /test/CodeGen/Thumb2 | |
parent | 2a3af681117a374062c21c96b2d63897eaceaabf (diff) |
[ARM] Improve if-conversion for M-class CPUs without branch predictors
The current heuristic in isProfitableToIfCvt assumes we have a branch predictor,
and so gives the wrong answer in some cases when we don't. This patch adds a
subtarget feature to indicate that a subtarget has no branch predictor, and
changes the heuristic in isProfitableToiIfCvt when it's present. This gives a
slight overall improvement in a set of embedded benchmarks on Cortex-M4 and
Cortex-M33.
Differential Revision: https://reviews.llvm.org/D34398
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306547 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/Thumb2')
-rw-r--r-- | test/CodeGen/Thumb2/ifcvt-no-branch-predictor.ll | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/test/CodeGen/Thumb2/ifcvt-no-branch-predictor.ll b/test/CodeGen/Thumb2/ifcvt-no-branch-predictor.ll new file mode 100644 index 00000000000..9fcc0f5d617 --- /dev/null +++ b/test/CodeGen/Thumb2/ifcvt-no-branch-predictor.ll @@ -0,0 +1,154 @@ +; RUN: llc < %s -mtriple=thumbv7m -mcpu=cortex-m7 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BP +; RUN: llc < %s -mtriple=thumbv7m -mcpu=cortex-m3 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOBP + +declare void @otherfn() + +; CHECK-LABEL: triangle1: +; CHECK: itt ne +; CHECK: movne +; CHECK: strne +define i32 @triangle1(i32 %n, i32* %p) { +entry: + %tobool = icmp eq i32 %n, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: + store i32 1, i32* %p, align 4 + br label %if.end + +if.end: + tail call void @otherfn() + ret i32 0 +} + +; CHECK-LABEL: triangle2: +; CHECK-BP: itttt ne +; CHECK-BP: movne +; CHECK-BP: strne +; CHECK-BP: movne +; CHECK-BP: strne +; CHECK-NOBP: cbz +; CHECK-NOBP: movs +; CHECK-NOBP: str +; CHECK-NOBP: movs +; CHECK-NOBP: str +define i32 @triangle2(i32 %n, i32* %p, i32* %q) { +entry: + %tobool = icmp eq i32 %n, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: + store i32 1, i32* %p, align 4 + store i32 2, i32* %q, align 4 + br label %if.end + +if.end: + tail call void @otherfn() + ret i32 0 +} + +; CHECK-LABEL: triangle3: +; CHECK: cbz +; CHECK: movs +; CHECK: str +; CHECK: movs +; CHECK: str +; CHECK: movs +; CHECK: str +define i32 @triangle3(i32 %n, i32* %p, i32* %q, i32* %r) { +entry: + %tobool = icmp eq i32 %n, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: + store i32 1, i32* %p, align 4 + store i32 2, i32* %q, align 4 + store i32 3, i32* %r, align 4 + br label %if.end + +if.end: + tail call void @otherfn() + ret i32 0 +} + +; CHECK-LABEL: diamond1: +; CHECK: ite eq +; CHECK: ldreq +; CHECK: strne +define i32 @diamond1(i32 %n, i32* %p) { +entry: + %tobool = icmp eq i32 %n, 0 + br i1 %tobool, label %if.else, label %if.then + +if.then: + store i32 %n, i32* %p, align 4 + br label %if.end + +if.else: + %0 = load i32, i32* %p, align 4 + br label %if.end + +if.end: + %n.addr.0 = phi i32 [ %n, %if.then ], [ %0, %if.else ] + tail call void @otherfn() + ret i32 %n.addr.0 +} + +; CHECK-LABEL: diamond2: +; CHECK-BP: itte +; CHECK-BP: streq +; CHECK-BP: ldreq +; CHECK-BP: strne +; CHECK-NOBP: cbz +; CHECK-NOBP: str +; CHECK-NOBP: b +; CHECK-NOBP: str +; CHECK-NOBP: ldr +define i32 @diamond2(i32 %n, i32 %m, i32* %p, i32* %q) { +entry: + %tobool = icmp eq i32 %n, 0 + br i1 %tobool, label %if.else, label %if.then + +if.then: + store i32 %n, i32* %p, align 4 + br label %if.end + +if.else: + store i32 %m, i32* %q, align 4 + %0 = load i32, i32* %p, align 4 + br label %if.end + +if.end: + %n.addr.0 = phi i32 [ %n, %if.then ], [ %0, %if.else ] + tail call void @otherfn() + ret i32 %n.addr.0 +} + +; CHECK-LABEL: diamond3: +; CHECK: cbz +; CHECK: movs +; CHECK: str +; CHECK: b +; CHECK: ldr +; CHECK: ldr +; CHECK: adds +define i32 @diamond3(i32 %n, i32* %p, i32* %q) { +entry: + %tobool = icmp eq i32 %n, 0 + br i1 %tobool, label %if.else, label %if.then + +if.then: + store i32 1, i32* %p, align 4 + br label %if.end + +if.else: + %0 = load i32, i32* %p, align 4 + %1 = load i32, i32* %q, align 4 + %add = add nsw i32 %1, %0 + br label %if.end + +if.end: + %n.addr.0 = phi i32 [ %n, %if.then ], [ %add, %if.else ] + tail call void @otherfn() + ret i32 %n.addr.0 +} |