diff options
author | Cameron Zwarich <zwarich@apple.com> | 2011-06-18 05:47:49 +0000 |
---|---|---|
committer | Cameron Zwarich <zwarich@apple.com> | 2011-06-18 05:47:49 +0000 |
commit | 6be41eb7f00319f5ffa1a5435dcd1e81b3ce932d (patch) | |
tree | 7d680994c23dd3fdf0b30512b4f8fa0c20448e92 | |
parent | aab3ea244cb014beb21c112729034879a5d4e5ee (diff) | |
download | external_llvm-6be41eb7f00319f5ffa1a5435dcd1e81b3ce932d.tar.gz external_llvm-6be41eb7f00319f5ffa1a5435dcd1e81b3ce932d.tar.bz2 external_llvm-6be41eb7f00319f5ffa1a5435dcd1e81b3ce932d.zip |
Fix an invalid bitcast crash that occurs when doing a partial memset of a vector
alloca. Fixes part of <rdar://problem/9580800>.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133336 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/ScalarReplAggregates.cpp | 18 | ||||
-rw-r--r-- | test/Transforms/ScalarRepl/2011-06-17-VectorPartialMemset.ll | 22 |
2 files changed, 37 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index bb4779b912..38942dcb55 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -521,10 +521,22 @@ bool ConvertToScalarInfo::CanConvertToScalar(Value *V, uint64_t Offset) { // If this is a constant sized memset of a constant value (e.g. 0) we can // handle it. if (MemSetInst *MSI = dyn_cast<MemSetInst>(User)) { - // Store of constant value and constant size. - if (!isa<ConstantInt>(MSI->getValue()) || - !isa<ConstantInt>(MSI->getLength())) + // Store of constant value. + if (!isa<ConstantInt>(MSI->getValue())) return false; + + // Store of constant size. + ConstantInt *Len = dyn_cast<ConstantInt>(MSI->getLength()); + if (!Len) + return false; + + // If the size differs from the alloca, we can only convert the alloca to + // an integer bag-of-bits. + // FIXME: This should handle all of the cases that are currently accepted + // as vector element insertions. + if (Len->getZExtValue() != AllocaSize || Offset != 0) + ScalarKind = Integer; + IsNotTrivial = true; // Can't be mem2reg'd. HadNonMemTransferAccess = true; continue; diff --git a/test/Transforms/ScalarRepl/2011-06-17-VectorPartialMemset.ll b/test/Transforms/ScalarRepl/2011-06-17-VectorPartialMemset.ll new file mode 100644 index 0000000000..29d195eba3 --- /dev/null +++ b/test/Transforms/ScalarRepl/2011-06-17-VectorPartialMemset.ll @@ -0,0 +1,22 @@ +; RUN: opt < %s -scalarrepl -S | FileCheck %s +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32" +target triple = "thumbv7-apple-darwin10" + +; CHECK: f +; CHECK-NOT: alloca +; CHECK: %[[A:[a-z0-9]*]] = and i128 undef, -16777216 +; CHECK: %[[B:[a-z0-9]*]] = bitcast i128 %[[A]] to <4 x float> +; CHECK: %[[C:[a-z0-9]*]] = extractelement <4 x float> %[[B]], i32 0 +; CHECK: ret float %[[C]] + +define float @f() nounwind ssp { +entry: + %a = alloca <4 x float>, align 16 + %p = bitcast <4 x float>* %a to i8* + call void @llvm.memset.p0i8.i32(i8* %p, i8 0, i32 3, i32 16, i1 false) + %vec = load <4 x float>* %a, align 8 + %val = extractelement <4 x float> %vec, i32 0 + ret float %val +} + +declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind |