aboutsummaryrefslogtreecommitdiffstats
path: root/test/Transforms/ScalarRepl/phi-select.ll
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2011-01-23 08:27:54 +0000
committerChris Lattner <sabre@nondot.org>2011-01-23 08:27:54 +0000
commit145c532e68acdf70d40bab5bc2034f692848b8dc (patch)
tree69d14295488caad4ccc9b6aa1d36d3219cef5663 /test/Transforms/ScalarRepl/phi-select.ll
parent491d8d43702a76b6d73ffbd85c368a4be51c44ae (diff)
downloadexternal_llvm-145c532e68acdf70d40bab5bc2034f692848b8dc.zip
external_llvm-145c532e68acdf70d40bab5bc2034f692848b8dc.tar.gz
external_llvm-145c532e68acdf70d40bab5bc2034f692848b8dc.tar.bz2
Enhance SRoA to be more aggressive about scalarization of aggregate allocas
that have PHI or select uses of their element pointers. This can often happen when instcombine sinks two loads into a successor, inserting a phi or select. With this patch, we can scalarize the alloca, but the pinned elements are not yet promoted. This is still a win for large aggregates where only one element is used. This fixes rdar://8904039 and part of rdar://7339113 (poor codegen on stringswitch). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124070 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/ScalarRepl/phi-select.ll')
-rw-r--r--test/Transforms/ScalarRepl/phi-select.ll78
1 files changed, 78 insertions, 0 deletions
diff --git a/test/Transforms/ScalarRepl/phi-select.ll b/test/Transforms/ScalarRepl/phi-select.ll
new file mode 100644
index 0000000..06ee208
--- /dev/null
+++ b/test/Transforms/ScalarRepl/phi-select.ll
@@ -0,0 +1,78 @@
+; RUN: opt %s -scalarrepl -S | FileCheck %s
+; Test promotion of allocas that have phis and select users.
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-apple-darwin10.2"
+
+%struct.X = type { i32 }
+%PairTy = type {i32, i32}
+
+; CHECK: @test1
+; CHECK: %a.0 = alloca i32
+; CHECK: %b.0 = alloca i32
+define i32 @test1(i32 %x) nounwind readnone ssp {
+entry:
+ %a = alloca %struct.X, align 8 ; <%struct.X*> [#uses=2]
+ %b = alloca %struct.X, align 8 ; <%struct.X*> [#uses=2]
+ %0 = getelementptr inbounds %struct.X* %a, i64 0, i32 0 ; <i32*> [#uses=1]
+ store i32 1, i32* %0, align 8
+ %1 = getelementptr inbounds %struct.X* %b, i64 0, i32 0 ; <i32*> [#uses=1]
+ store i32 2, i32* %1, align 8
+ %2 = icmp eq i32 %x, 0 ; <i1> [#uses=1]
+ %p.0 = select i1 %2, %struct.X* %b, %struct.X* %a ; <%struct.X*> [#uses=1]
+ %3 = getelementptr inbounds %struct.X* %p.0, i64 0, i32 0 ; <i32*> [#uses=1]
+ %4 = load i32* %3, align 8 ; <i32> [#uses=1]
+ ret i32 %4
+}
+
+; CHECK: @test2
+; CHECK: %A.0 = alloca i32
+; CHECK: %A.1 = alloca i32
+define i32 @test2(i1 %c) {
+entry:
+ %A = alloca {i32, i32}
+ %B = getelementptr {i32, i32}* %A, i32 0, i32 0
+ store i32 1, i32* %B
+ br i1 %c, label %T, label %F
+T:
+ %C = getelementptr {i32, i32}* %A, i32 0, i32 1
+ store i32 2, i32* %B
+ br label %F
+F:
+ %X = phi i32* [%B, %entry], [%C, %T]
+ %Q = load i32* %X
+ ret i32 %Q
+}
+
+; CHECK: @test3
+; CHECK: %A.0 = alloca i32
+; CHECK: %A.1 = alloca i32
+; rdar://8904039
+define i32 @test3(i1 %c) {
+entry:
+ %A = alloca {i32, i32}
+ %B = getelementptr {i32, i32}* %A, i32 0, i32 0
+ store i32 1, i32* %B
+ %C = getelementptr {i32, i32}* %A, i32 0, i32 1
+ store i32 2, i32* %B
+
+ %X = select i1 %c, i32* %B, i32* %C
+ %Q = load i32* %X
+ ret i32 %Q
+}
+
+;; We can't scalarize this, a use of the select is not an element access.
+define i64 @test4(i1 %c) {
+entry:
+ %A = alloca %PairTy
+ ; CHECK: @test4
+ ; CHECK: %A = alloca %PairTy
+ %B = getelementptr {i32, i32}* %A, i32 0, i32 0
+ store i32 1, i32* %B
+ %C = getelementptr {i32, i32}* %A, i32 0, i32 1
+ store i32 2, i32* %B
+
+ %X = select i1 %c, i32* %B, i32* %C
+ %Y = bitcast i32* %X to i64*
+ %Q = load i64* %Y
+ ret i64 %Q
+}