diff options
author | Hans Wennborg <hans@hanshq.net> | 2012-09-19 07:48:16 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2012-09-19 07:48:16 +0000 |
commit | 93ba133906da4b12a7c732b897e64541cc570120 (patch) | |
tree | cd97e0faeeb7ea03ea49307714e841716d478883 /test/Transforms/CodeGenPrepare | |
parent | 8a312fb3aaec90537d434a5cc41edf566ff80dca (diff) | |
download | llvm-93ba133906da4b12a7c732b897e64541cc570120.tar.gz llvm-93ba133906da4b12a7c732b897e64541cc570120.tar.bz2 llvm-93ba133906da4b12a7c732b897e64541cc570120.tar.xz |
CodeGenPrep: turn lookup tables into switches for some targets.
This is a follow-up from r163302, which added a transformation to
SimplifyCFG that turns some switches into loads from lookup tables.
It was pointed out that some targets, such as GPUs and deeply embedded
targets, might not find this appropriate, but SimplifyCFG doesn't have
enough information about the target to decide this.
This patch adds the reverse transformation to CodeGenPrep: it turns
loads from lookup tables back into switches for targets where we do not
build jump tables (assuming these are also the targets where lookup
tables are inappropriate).
Hopefully we will eventually get to have target information in
SimplifyCFG, and then this CodeGenPrep transformation can be removed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164206 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/CodeGenPrepare')
-rw-r--r-- | test/Transforms/CodeGenPrepare/load_to_switch.ll | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/test/Transforms/CodeGenPrepare/load_to_switch.ll b/test/Transforms/CodeGenPrepare/load_to_switch.ll new file mode 100644 index 0000000000..76a57c6b50 --- /dev/null +++ b/test/Transforms/CodeGenPrepare/load_to_switch.ll @@ -0,0 +1,84 @@ +; RUN: llc -march=sparc < %s | FileCheck %s + +; Check that all the switches turned into lookup tables by SimplifyCFG are +; turned back into switches for targets that don't like lookup tables. + +@.str = private unnamed_addr constant [4 x i8] c"foo\00", align 1 +@.str1 = private unnamed_addr constant [4 x i8] c"bar\00", align 1 +@.str2 = private unnamed_addr constant [4 x i8] c"baz\00", align 1 +@.str3 = private unnamed_addr constant [4 x i8] c"qux\00", align 1 +@.str4 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@switch.table = private unnamed_addr constant [7 x i32] [i32 55, i32 123, i32 0, i32 -1, i32 27, i32 62, i32 1] +@switch.table1 = private unnamed_addr constant [4 x i8] c"*\09X\05" +@switch.table2 = private unnamed_addr constant [4 x float] [float 0x40091EB860000000, float 0x3FF3BE76C0000000, float 0x4012449BA0000000, float 0x4001AE1480000000] +@switch.table3 = private unnamed_addr constant [4 x i8*] [i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8]* @.str1, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8]* @.str2, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8]* @.str3, i64 0, i64 0)] + +define i32 @f(i32 %c) { +entry: + %switch.tableidx = sub i32 %c, 42 + %0 = icmp ult i32 %switch.tableidx, 7 + br i1 %0, label %switch.lookup, label %return + +switch.lookup: + %switch.gep = getelementptr inbounds [7 x i32]* @switch.table, i32 0, i32 %switch.tableidx + %switch.load = load i32* %switch.gep + ret i32 %switch.load + +return: + ret i32 15 + +; CHECK: f: +; CHECK: %switch.lookup +; CHECK-NOT: sethi %hi(.Lswitch.table) +} + +declare void @dummy(i8 signext, float) + +define void @h(i32 %x) { +entry: + %switch.tableidx = sub i32 %x, 0 + %0 = icmp ult i32 %switch.tableidx, 4 + br i1 %0, label %switch.lookup, label %sw.epilog + +switch.lookup: + %switch.gep = getelementptr inbounds [4 x i8]* @switch.table1, i32 0, i32 %switch.tableidx + %switch.load = load i8* %switch.gep + %switch.gep1 = getelementptr inbounds [4 x float]* @switch.table2, i32 0, i32 %switch.tableidx + %switch.load2 = load float* %switch.gep1 + br label %sw.epilog + +sw.epilog: + %a.0 = phi i8 [ %switch.load, %switch.lookup ], [ 7, %entry ] + %b.0 = phi float [ %switch.load2, %switch.lookup ], [ 0x4023FAE140000000, %entry ] + call void @dummy(i8 signext %a.0, float %b.0) + ret void + +; CHECK: h: +; CHECK: %switch.lookup +; CHECK-NOT: sethi %hi(.Lswitch.table{{[0-9]}}) +; CHECK-NOT: sethi %hi(.Lswitch.table{{[0-9]}}) +} + +define i8* @foostring(i32 %x) { +entry: + %switch.tableidx = sub i32 %x, 0 + %0 = icmp ult i32 %switch.tableidx, 4 + br i1 %0, label %switch.lookup, label %return + +switch.lookup: + %switch.gep = getelementptr inbounds [4 x i8*]* @switch.table3, i32 0, i32 %switch.tableidx + %switch.load = load i8** %switch.gep + ret i8* %switch.load + +return: + ret i8* getelementptr inbounds ([6 x i8]* @.str4, i64 0, i64 0) + +; CHECK: foostring: +; CHECK: %switch.lookup +; CHECK-NOT: sethi %hi(.Lswitch.table3) +} + +; CHECK-NOT: .Lswitch.table +; CHECK-NOT: .Lswitch.table1 +; CHECK-NOT: .Lswitch.table2 +; CHECK-NOT: .Lswitch.table3 |