summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2015-02-12 02:30:56 +0000
committerChandler Carruth <chandlerc@gmail.com>2015-02-12 02:30:56 +0000
commit63aaa98d94afaf7b1fd73d8b50a00ebf7392ba83 (patch)
treed8288b9a1eb3e329608bee955d7d800316dcce10 /llvm/test/Transforms
parent15b385f8547e6d7236b39e66a8d3a53df5b3f454 (diff)
downloadbcm5719-llvm-63aaa98d94afaf7b1fd73d8b50a00ebf7392ba83.tar.gz
bcm5719-llvm-63aaa98d94afaf7b1fd73d8b50a00ebf7392ba83.zip
[slp] Fix a nasty bug in the SLP vectorizer that Joerg pointed out.
Apparently some code finally started to tickle this after my canonicalization changes to instcombine. The bug stems from trying to form a vector type out of scalars that aren't compatible at all. In this example, from x86_mmx values. The code in the vectorizer that checks for reasonable types whas checking for aggregates or vectors, but there are lots of other types that should just never reach the vectorizer. Debugging this was made more confusing by the lie in an assert in VectorType::get() -- it isn't that the types are *primitive*. The types must be integer, pointer, or floating point types. No other types are allowed. I've improved the assert and added a helper to the vectorizer to handle the element type validity checks. It now re-uses the VectorType static function and then further excludes weird target-specific types that we probably shouldn't be touching here (x86_fp80 and ppc_fp128). Neither of these are really reachable anyways (neither 80-bit nor 128-bit things will get vectorized) but it seems better to just eagerly exclude such nonesense. I've added a test case, but while it definitely covers two of the paths through this code there may be more paths that would benefit from test coverage. I'm not familiar enough with the SLP vectorizer to synthesize test cases for all of these, but was able to update the code itself by inspection. llvm-svn: 228899
Diffstat (limited to 'llvm/test/Transforms')
-rw-r--r--llvm/test/Transforms/SLPVectorizer/X86/bad_types.ll50
1 files changed, 50 insertions, 0 deletions
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/bad_types.ll b/llvm/test/Transforms/SLPVectorizer/X86/bad_types.ll
new file mode 100644
index 00000000000..38ed18dad2a
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/bad_types.ll
@@ -0,0 +1,50 @@
+; RUN: opt < %s -basicaa -slp-vectorizer -S -mcpu=corei7-avx | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @test1(x86_mmx %a, x86_mmx %b, i64* %ptr) {
+; Ensure we can handle x86_mmx values which are primitive and can be bitcast
+; with integer types but can't be put into a vector.
+;
+; CHECK-LABEL: @test1
+; CHECK: store i64
+; CHECK: store i64
+; CHECK: ret void
+entry:
+ %a.cast = bitcast x86_mmx %a to i64
+ %b.cast = bitcast x86_mmx %b to i64
+ %a.and = and i64 %a.cast, 42
+ %b.and = and i64 %b.cast, 42
+ %gep = getelementptr i64* %ptr, i32 1
+ store i64 %a.and, i64* %ptr
+ store i64 %b.and, i64* %gep
+ ret void
+}
+
+define void @test2(x86_mmx %a, x86_mmx %b) {
+; Same as @test1 but using phi-input vectorization instead of store
+; vectorization.
+;
+; CHECK-LABEL: @test2
+; CHECK: and i64
+; CHECK: and i64
+; CHECK: ret void
+entry:
+ br i1 undef, label %if.then, label %exit
+
+if.then:
+ %a.cast = bitcast x86_mmx %a to i64
+ %b.cast = bitcast x86_mmx %b to i64
+ %a.and = and i64 %a.cast, 42
+ %b.and = and i64 %b.cast, 42
+ br label %exit
+
+exit:
+ %a.phi = phi i64 [ 0, %entry ], [ %a.and, %if.then ]
+ %b.phi = phi i64 [ 0, %entry ], [ %b.and, %if.then ]
+ tail call void @f(i64 %a.phi, i64 %b.phi)
+ ret void
+}
+
+declare void @f(i64, i64)
OpenPOWER on IntegriCloud