summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/SimplifyCFG
diff options
context:
space:
mode:
authorOliver Stannard <oliver.stannard@arm.com>2016-10-07 08:48:24 +0000
committerOliver Stannard <oliver.stannard@arm.com>2016-10-07 08:48:24 +0000
commit4df1cc0b00f7ee72a1841de2080d9a4f7a1a6955 (patch)
tree5ee57a9ce646cdb5ce5858ca4d695e36f81741df /llvm/test/Transforms/SimplifyCFG
parent68c6c8cd782d204e040e676f4bdfb8b4b7210a3e (diff)
downloadbcm5719-llvm-4df1cc0b00f7ee72a1841de2080d9a4f7a1a6955.tar.gz
bcm5719-llvm-4df1cc0b00f7ee72a1841de2080d9a4f7a1a6955.zip
[ARM] Don't convert switches to lookup tables of pointers with ROPI/RWPI
With the ROPI and RWPI relocation models we can't always have pointers to global data or functions in constant data, so don't try to convert switches into lookup tables if any value in the lookup table would require a relocation. We can still safely emit lookup tables of other values, such as simple constants. Differential Revision: https://reviews.llvm.org/D24462 llvm-svn: 283530
Diffstat (limited to 'llvm/test/Transforms/SimplifyCFG')
-rw-r--r--llvm/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll132
1 files changed, 132 insertions, 0 deletions
diff --git a/llvm/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll b/llvm/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll
new file mode 100644
index 00000000000..16f028d2e85
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/ARM/switch-to-lookup-table.ll
@@ -0,0 +1,132 @@
+; RUN: opt -S -simplifycfg -mtriple=arm -relocation-model=static < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
+; RUN: opt -S -simplifycfg -mtriple=arm -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
+; RUN: opt -S -simplifycfg -mtriple=arm -relocation-model=ropi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
+; RUN: opt -S -simplifycfg -mtriple=arm -relocation-model=rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
+; RUN: opt -S -simplifycfg -mtriple=arm -relocation-model=ropi-rwpi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
+
+; CHECK: @{{.*}} = private unnamed_addr constant [3 x i32] [i32 1234, i32 5678, i32 15532]
+; ENABLE: @{{.*}} = private unnamed_addr constant [3 x i32*] [i32* @c1, i32* @c2, i32* @c3]
+; DISABLE-NOT: @{{.*}} = private unnamed_addr constant [3 x i32*] [i32* @c1, i32* @c2, i32* @c3]
+; ENABLE: @{{.*}} = private unnamed_addr constant [3 x i32*] [i32* @g1, i32* @g2, i32* @g3]
+; DISABLE-NOT: @{{.*}} = private unnamed_addr constant [3 x i32*] [i32* @g1, i32* @g2, i32* @g3]
+; ENABLE: @{{.*}} = private unnamed_addr constant [3 x i32 (i32, i32)*] [i32 (i32, i32)* @f1, i32 (i32, i32)* @f2, i32 (i32, i32)* @f3]
+; DISABLE-NOT: @{{.*}} = private unnamed_addr constant [3 x i32 (i32, i32)*] [i32 (i32, i32)* @f1, i32 (i32, i32)* @f2, i32 (i32, i32)* @f3]
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "armv7a--none-eabi"
+
+define i32 @test1(i32 %n) {
+entry:
+ switch i32 %n, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ ]
+
+sw.bb:
+ br label %return
+
+sw.bb1:
+ br label %return
+
+sw.bb2:
+ br label %return
+
+sw.default:
+ br label %return
+
+return:
+ %retval.0 = phi i32 [ 15498, %sw.default ], [ 15532, %sw.bb2 ], [ 5678, %sw.bb1 ], [ 1234, %sw.bb ]
+ ret i32 %retval.0
+}
+
+@c1 = external constant i32, align 4
+@c2 = external constant i32, align 4
+@c3 = external constant i32, align 4
+@c4 = external constant i32, align 4
+
+
+define i32* @test2(i32 %n) {
+entry:
+ switch i32 %n, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ ]
+
+sw.bb:
+ br label %return
+
+sw.bb1:
+ br label %return
+
+sw.bb2:
+ br label %return
+
+sw.default:
+ br label %return
+
+return:
+ %retval.0 = phi i32* [ @c4, %sw.default ], [ @c3, %sw.bb2 ], [ @c2, %sw.bb1 ], [ @c1, %sw.bb ]
+ ret i32* %retval.0
+}
+
+@g1 = external global i32, align 4
+@g2 = external global i32, align 4
+@g3 = external global i32, align 4
+@g4 = external global i32, align 4
+
+define i32* @test3(i32 %n) {
+entry:
+ switch i32 %n, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ ]
+
+sw.bb:
+ br label %return
+
+sw.bb1:
+ br label %return
+
+sw.bb2:
+ br label %return
+
+sw.default:
+ br label %return
+
+return:
+ %retval.0 = phi i32* [ @g4, %sw.default ], [ @g3, %sw.bb2 ], [ @g2, %sw.bb1 ], [ @g1, %sw.bb ]
+ ret i32* %retval.0
+}
+
+declare i32 @f1(i32, i32)
+declare i32 @f2(i32, i32)
+declare i32 @f3(i32, i32)
+declare i32 @f4(i32, i32)
+declare i32 @f5(i32, i32)
+
+define i32 @test4(i32 %a, i32 %b, i32 %c) {
+entry:
+ %cmp = icmp eq i32 %a, 1
+ br i1 %cmp, label %cond.end11, label %cond.false
+
+cond.false:
+ %cmp1 = icmp eq i32 %a, 2
+ br i1 %cmp1, label %cond.end11, label %cond.false3
+
+cond.false3:
+ %cmp4 = icmp eq i32 %a, 3
+ br i1 %cmp4, label %cond.end11, label %cond.false6
+
+cond.false6:
+ %cmp7 = icmp eq i32 %a, 4
+ %cond = select i1 %cmp7, i32 (i32, i32)* @f4, i32 (i32, i32)* @f5
+ br label %cond.end11
+
+cond.end11:
+ %cond12 = phi i32 (i32, i32)* [ @f1, %entry ], [ @f2, %cond.false ], [ %cond, %cond.false6 ], [ @f3, %cond.false3 ]
+ %call = call i32 %cond12(i32 %b, i32 %c) #2
+ ret i32 %call
+}
OpenPOWER on IntegriCloud