OSDN Git Service

[LSV] Don't assume that bitcast ops are Instructions.
authorJustin Lebar <jlebar@google.com>
Wed, 27 Jul 2016 21:45:48 +0000 (21:45 +0000)
committerJustin Lebar <jlebar@google.com>
Wed, 27 Jul 2016 21:45:48 +0000 (21:45 +0000)
Summary:
When we ask the builder to create a bitcast on a constant, we get back a
constant, not an instruction.

Reviewers: asbirlea

Subscribers: jholewinski, mzolotukhin, llvm-commits, arsenm

Differential Revision: https://reviews.llvm.org/D22878

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276922 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Vectorize/LoadStoreVectorizer.cpp
test/Transforms/LoadStoreVectorizer/NVPTX/non-instr-bitcast.ll [new file with mode: 0644]

index 804db41..acec94e 100644 (file)
@@ -969,8 +969,6 @@ bool Vectorizer::vectorizeLoadChain(
 
   if (VecLoadTy) {
     SmallVector<Instruction *, 16> InstrsToErase;
-    SmallVector<Instruction *, 16> InstrsToReorder;
-    InstrsToReorder.push_back(cast<Instruction>(Bitcast));
 
     unsigned VecWidth = VecLoadTy->getNumElements();
     for (unsigned I = 0, E = Chain.size(); I != E; ++I) {
@@ -990,15 +988,14 @@ bool Vectorizer::vectorizeLoadChain(
       }
     }
 
-    for (Instruction *ModUser : InstrsToReorder)
-      reorder(ModUser);
+    // Bitcast might not be an Instruction, if the value being loaded is a
+    // constant.  In that case, no need to reorder anything.
+    if (Instruction *BitcastInst = dyn_cast<Instruction>(Bitcast))
+      reorder(BitcastInst);
 
     for (auto I : InstrsToErase)
       I->eraseFromParent();
   } else {
-    SmallVector<Instruction *, 16> InstrsToReorder;
-    InstrsToReorder.push_back(cast<Instruction>(Bitcast));
-
     for (unsigned I = 0, E = Chain.size(); I != E; ++I) {
       Value *V = Builder.CreateExtractElement(LI, Builder.getInt32(I));
       Instruction *Extracted = cast<Instruction>(V);
@@ -1012,8 +1009,8 @@ bool Vectorizer::vectorizeLoadChain(
       UI->replaceAllUsesWith(Extracted);
     }
 
-    for (Instruction *ModUser : InstrsToReorder)
-      reorder(ModUser);
+    if (Instruction *BitcastInst = dyn_cast<Instruction>(Bitcast))
+      reorder(BitcastInst);
   }
 
   eraseInstructions(Chain);
diff --git a/test/Transforms/LoadStoreVectorizer/NVPTX/non-instr-bitcast.ll b/test/Transforms/LoadStoreVectorizer/NVPTX/non-instr-bitcast.ll
new file mode 100644 (file)
index 0000000..c8c3c51
--- /dev/null
@@ -0,0 +1,14 @@
+; RUN: opt -mtriple=nvptx64-nvidia-cuda -load-store-vectorizer -S -o - %s | FileCheck %s
+
+; Load from a constant.  This can be vectorized, but shouldn't crash us.
+
+@global = internal addrspace(1) constant [4 x float] [float 0xBF71111120000000, float 0x3F70410420000000, float 0xBF81111120000000, float 0x3FB5555560000000], align 4
+
+define void @foo() {
+  ; CHECK: load <4 x float>
+  %a = load float, float addrspace(1)* getelementptr inbounds ([4 x float], [4 x float] addrspace(1)* @global, i64 0, i64 0), align 4
+  %b = load float, float addrspace(1)* getelementptr inbounds ([4 x float], [4 x float] addrspace(1)* @global, i64 0, i64 1), align 4
+  %c = load float, float addrspace(1)* getelementptr inbounds ([4 x float], [4 x float] addrspace(1)* @global, i64 0, i64 2), align 4
+  %d = load float, float addrspace(1)* getelementptr inbounds ([4 x float], [4 x float] addrspace(1)* @global, i64 0, i64 3), align 4
+  ret void
+}