diff options
| author | Joey Gouly <joey.gouly@arm.com> | 2013-11-21 17:09:05 +0000 |
|---|---|---|
| committer | Joey Gouly <joey.gouly@arm.com> | 2013-11-21 17:09:05 +0000 |
| commit | cf4143b55e881519b06295e6954778d00f949c43 (patch) | |
| tree | 1cdbcd38065fc5137da4d40712d174293751989c /clang | |
| parent | dd3e75449f4da97194100374972445bcc4f9d2de (diff) | |
| download | bcm5719-llvm-cf4143b55e881519b06295e6954778d00f949c43.tar.gz bcm5719-llvm-cf4143b55e881519b06295e6954778d00f949c43.zip | |
Fix a crash in EmitStoreThroughExtVectorComponentLValue for vectors of odd sizes.
In OpenCL a vector of 3 elements, acts like a vector of four elements.
So for a vector of size 3 the '.hi' and '.odd' accessors, would access
the elements {2, 3} and {1, 3} respectively.
However, in EmitStoreThroughExtVectorComponentLValue we are still operating on
a vector of size 3, so we should only access {2} and {1}. We do this by checking
the last element to be accessed, and ignore it if it is out-of-bounds.
EmitLoadOfExtVectorElementLValue doesn't have a similar problem, because it does
a direct shufflevector with undef, so an out-of-bounds access just gives an undef
value.
Patch by Anastasia Stulova!
llvm-svn: 195367
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 6 | ||||
| -rw-r--r-- | clang/test/CodeGenOpenCL/vector_odd.cl | 17 |
2 files changed, 23 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index be50f4e10f7..cb990b243fb 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1553,6 +1553,12 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src, for (unsigned i = 0; i != NumDstElts; ++i) Mask.push_back(Builder.getInt32(i)); + // When the vector size is odd and .odd or .hi is used, the last element + // of the Elts constant array will be one past the size of the vector. + // Ignore the last element here, if it is greater than the mask size. + if (getAccessedFieldNo(NumSrcElts - 1, Elts) == Mask.size()) + NumSrcElts--; + // modify when what gets shuffled in for (unsigned i = 0; i != NumSrcElts; ++i) Mask[getAccessedFieldNo(i, Elts)] = Builder.getInt32(i+NumDstElts); diff --git a/clang/test/CodeGenOpenCL/vector_odd.cl b/clang/test/CodeGenOpenCL/vector_odd.cl new file mode 100644 index 00000000000..c44328bfaa7 --- /dev/null +++ b/clang/test/CodeGenOpenCL/vector_odd.cl @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 %s -O0 -emit-llvm -o - | FileCheck %s + +typedef unsigned char __attribute__((ext_vector_type(3))) uchar3; + +//CHECK: {{%.*}} = shufflevector <3 x i8> {{%.*}}, <3 x i8> <i8 1, i8 1, i8 undef>, <3 x i32> <i32 0, i32 3, i32 2> + +kernel void test_odd_vector1 (uchar3 lhs) +{ + lhs.odd = 1; +} + +//CHECK: {{%.*}} = shufflevector <3 x i8> {{%.*}}, <3 x i8> <i8 2, i8 2, i8 undef>, <3 x i32> <i32 0, i32 1, i32 3> + +kernel void test_odd_vector2 (uchar3 lhs) +{ + lhs.hi = 2; +} |

