summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerolf Hoflehner <ghoflehner@apple.com>2016-05-23 19:23:17 +0000
committerGerolf Hoflehner <ghoflehner@apple.com>2016-05-23 19:23:17 +0000
commit396a19fe6734b4be43b59ad498b7a5b095aa6871 (patch)
tree25d485cc311ae8fa64a517ef7fc23ae24b0ee458
parent4b3e216784a47fb304c0ddeac00d0e54b03ba564 (diff)
[InstCombine] Fix assertion when bitcast is converted to gep
When an aggregate contains an opaque type its size cannot be determined. This triggers an "Invalid GetElementPtrInst indices for type" assert in function checkGEPType. The fix suppresses the conversion in this case. http://reviews.llvm.org/D20319 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270479 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/InstCombine/InstCombineCasts.cpp7
-rw-r--r--test/Transforms/InstCombine/opaque.ll32
2 files changed, 39 insertions, 0 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 80b138e8c36..dddcd0183b3 100644
--- a/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1922,6 +1922,13 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
if (Instruction *V = PromoteCastOfAllocation(CI, *AI))
return V;
+ // When the type pointed to is not sized the cast cannot be
+ // turned into a gep.
+ Type *PointeeType =
+ cast<PointerType>(Src->getType()->getScalarType())->getElementType();
+ if (!PointeeType->isSized())
+ return nullptr;
+
// If the source and destination are pointers, and this cast is equivalent
// to a getelementptr X, 0, 0, 0... turn it into the appropriate gep.
// This can enhance SROA and other transforms that want type-safe pointers.
diff --git a/test/Transforms/InstCombine/opaque.ll b/test/Transforms/InstCombine/opaque.ll
new file mode 100644
index 00000000000..f2a91855d5a
--- /dev/null
+++ b/test/Transforms/InstCombine/opaque.ll
@@ -0,0 +1,32 @@
+; RUN: opt < %s -instcombine -disable-output
+; Checks that bitcasts are not converted into GEP when
+; when the size of an aggregate cannot be determined.
+%swift.opaque = type opaque
+%SQ = type <{ [8 x i8] }>
+%Si = type <{ i64 }>
+
+%V = type <{ <{ %Vs4Int8, %Vs4Int8, %Vs4Int8, %Vs4Int8, %Vs4Int8, %Vs4Int8, %Vs4Int8, %Vs4Int8 }>, %Si, %SQ, %SQ, %Si, %swift.opaque }>
+%Vs4Int8 = type <{ i8 }>
+%swift.type = type { i64 }
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly,
+i64, i32, i1) #8
+
+@_swift_slowAlloc = external global i8* (i64, i64)*
+
+declare i8* @rt_swift_slowAlloc(i64, i64)
+
+define %swift.opaque* @_TwTkV([24 x i8]* %dest, %swift.opaque* %src,
+%swift.type* %bios_boot_params) #0 {
+entry:
+ %0 = bitcast %swift.opaque* %src to %V*
+ %1 = call noalias i8* @rt_swift_slowAlloc(i64 40, i64 0) #11
+ %2 = bitcast [24 x i8]* %dest to i8**
+ store i8* %1, i8** %2, align 8
+ %3 = bitcast i8* %1 to %V*
+ %4 = bitcast %V* %3 to i8*
+ %5 = bitcast %V* %0 to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %4, i8* %5, i64 40, i32 1, i1 false)
+ %6 = bitcast %V* %3 to %swift.opaque*
+ ret %swift.opaque* %6
+}