[llvm] r187506 - Reject bitcasts between address spaces with different sizes

Matt Arsenault Matthew.Arsenault at amd.com
Wed Jul 31 10:49:08 PDT 2013


Author: arsenm
Date: Wed Jul 31 12:49:08 2013
New Revision: 187506

URL: http://llvm.org/viewvc/llvm-project?rev=187506&view=rev
Log:
Reject bitcasts between address spaces with different sizes

Added:
    llvm/trunk/test/Verifier/bitcast-address-space-nested-global-cycle.ll
    llvm/trunk/test/Verifier/bitcast-address-space-nested-global.ll
    llvm/trunk/test/Verifier/bitcast-address-space-through-constant-inttoptr-inside-gep-instruction.ll
    llvm/trunk/test/Verifier/bitcast-address-space-through-constant-inttoptr.ll
    llvm/trunk/test/Verifier/bitcast-address-space-through-gep-2.ll
    llvm/trunk/test/Verifier/bitcast-address-space-through-gep.ll
    llvm/trunk/test/Verifier/bitcast-address-space-through-inttoptr.ll
    llvm/trunk/test/Verifier/bitcast-address-spaces.ll
    llvm/trunk/test/Verifier/bitcast-vector-pointer-as.ll
Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/lib/IR/Verifier.cpp

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=187506&r1=187505&r2=187506&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Wed Jul 31 12:49:08 2013
@@ -1061,7 +1061,9 @@ the specifications in the ``datalayout``
 specifications are given in this list:
 
 -  ``E`` - big endian
--  ``p:64:64:64`` - 64-bit pointers with 64-bit alignment
+-  ``p:64:64:64`` - 64-bit pointers with 64-bit alignment.
+-  ``p[n]:64:64:64`` - Other address spaces are assumed to be the
+   same as the default address space.
 -  ``S0`` - natural stack alignment is unspecified
 -  ``i1:8:8`` - i1 is 8-bit (byte) aligned
 -  ``i8:8:8`` - i8 is 8-bit (byte) aligned
@@ -2583,7 +2585,7 @@ Examples:
 It is sometimes useful to attach information to loop constructs. Currently,
 loop metadata is implemented as metadata attached to the branch instruction
 in the loop latch block. This type of metadata refer to a metadata node that is
-guaranteed to be separate for each loop. The loop identifier metadata is 
+guaranteed to be separate for each loop. The loop identifier metadata is
 specified with the name ``llvm.loop``.
 
 The loop identifier metadata is implemented using a metadata that refers to
@@ -5613,24 +5615,24 @@ Arguments:
 
 The '``bitcast``' instruction takes a value to cast, which must be a
 non-aggregate first class value, and a type to cast it to, which must
-also be a non-aggregate :ref:`first class <t_firstclass>` type. The bit
-sizes of ``value`` and the destination type, ``ty2``, must be identical.
-If the source type is a pointer, the destination type must also be a
-pointer. This instruction supports bitwise conversion of vectors to
-integers and to vectors of other types (as long as they have the same
-size).
+also be a non-aggregate :ref:`first class <t_firstclass>` type. The
+bit sizes of ``value`` and the destination type, ``ty2``, must be
+identical.  If the source type is a pointer, the destination type must
+also be a pointer of the same size. This instruction supports bitwise
+conversion of vectors to integers and to vectors of other types (as
+long as they have the same size).
 
 Semantics:
 """"""""""
 
-The '``bitcast``' instruction converts ``value`` to type ``ty2``. It is
-always a *no-op cast* because no bits change with this conversion. The
-conversion is done as if the ``value`` had been stored to memory and
-read back as type ``ty2``. Pointer (or vector of pointers) types may
-only be converted to other pointer (or vector of pointers) types with
-this instruction. To convert pointers to other types, use the
-:ref:`inttoptr <i_inttoptr>` or :ref:`ptrtoint <i_ptrtoint>` instructions
-first.
+The '``bitcast``' instruction converts ``value`` to type ``ty2``. It
+is always a *no-op cast* because no bits change with this
+conversion. The conversion is done as if the ``value`` had been stored
+to memory and read back as type ``ty2``. Pointer (or vector of
+pointers) types may only be converted to other pointer (or vector of
+pointers) types with this instruction if the pointer sizes are
+equal. To convert pointers to other types, use the :ref:`inttoptr
+<i_inttoptr>` or :ref:`ptrtoint <i_ptrtoint>` instructions first.
 
 Example:
 """"""""

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=187506&r1=187505&r2=187506&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Wed Jul 31 12:49:08 2013
@@ -56,6 +56,7 @@
 #include "llvm/DebugInfo.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/IntrinsicInst.h"
@@ -128,6 +129,7 @@ namespace {
     Module *Mod;          // Module we are verifying right now
     LLVMContext *Context; // Context within which we are verifying
     DominatorTree *DT;    // Dominator Tree, caution can be null!
+    const DataLayout *DL;
 
     std::string Messages;
     raw_string_ostream MessagesStr;
@@ -152,13 +154,13 @@ namespace {
 
     Verifier()
       : FunctionPass(ID), Broken(false),
-        action(AbortProcessAction), Mod(0), Context(0), DT(0),
+        action(AbortProcessAction), Mod(0), Context(0), DT(0), DL(0),
         MessagesStr(Messages), PersonalityFn(0) {
       initializeVerifierPass(*PassRegistry::getPassRegistry());
     }
     explicit Verifier(VerifierFailureAction ctn)
       : FunctionPass(ID), Broken(false), action(ctn), Mod(0),
-        Context(0), DT(0), MessagesStr(Messages), PersonalityFn(0) {
+        Context(0), DT(0), DL(0), MessagesStr(Messages), PersonalityFn(0) {
       initializeVerifierPass(*PassRegistry::getPassRegistry());
     }
 
@@ -167,6 +169,8 @@ namespace {
       Context = &M.getContext();
       Finder.reset();
 
+      DL = getAnalysisIfAvailable<DataLayout>();
+
       // We must abort before returning back to the pass manager, or else the
       // pass manager may try to run other passes on the broken module.
       return abortIfBroken();
@@ -321,6 +325,9 @@ namespace {
     void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
                              const Value *V);
 
+    void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy);
+    void VerifyConstantExprBitcastType(const ConstantExpr *CE);
+
     void verifyDebugInfo(Module &M);
 
     void WriteValue(const Value *V) {
@@ -487,6 +494,33 @@ void Verifier::visitGlobalVariable(Globa
     }
   }
 
+  if (!GV.hasInitializer()) {
+    visitGlobalValue(GV);
+    return;
+  }
+
+  // Walk any aggregate initializers looking for bitcasts between address spaces
+  SmallPtrSet<const Value *, 4> Visited;
+  SmallVector<const Value *, 4> WorkStack;
+  WorkStack.push_back(cast<Value>(GV.getInitializer()));
+
+  while (!WorkStack.empty()) {
+    const Value *V = WorkStack.pop_back_val();
+    if (!Visited.insert(V))
+      continue;
+
+    if (const User *U = dyn_cast<User>(V)) {
+      for (unsigned I = 0, N = U->getNumOperands(); I != N; ++I)
+        WorkStack.push_back(U->getOperand(I));
+    }
+
+    if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
+      VerifyConstantExprBitcastType(CE);
+      if (Broken)
+        return;
+    }
+  }
+
   visitGlobalValue(GV);
 }
 
@@ -865,6 +899,52 @@ void Verifier::VerifyFunctionAttrs(Funct
           "Attributes 'noinline and alwaysinline' are incompatible!", V);
 }
 
+void Verifier::VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy) {
+  // Get the size of the types in bits, we'll need this later
+  unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
+  unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
+
+  // BitCast implies a no-op cast of type only. No bits change.
+  // However, you can't cast pointers to anything but pointers.
+  Assert1(SrcTy->isPointerTy() == DestTy->isPointerTy(),
+          "Bitcast requires both operands to be pointer or neither", V);
+  Assert1(SrcBitSize == DestBitSize,
+          "Bitcast requires types of same width", V);
+
+  // Disallow aggregates.
+  Assert1(!SrcTy->isAggregateType(),
+          "Bitcast operand must not be aggregate", V);
+  Assert1(!DestTy->isAggregateType(),
+          "Bitcast type must not be aggregate", V);
+
+  // Without datalayout, assume all address spaces are the same size.
+  // Don't check if both types are not pointers.
+  // Skip casts between scalars and vectors.
+  if (!DL ||
+      !SrcTy->isPtrOrPtrVectorTy() ||
+      !DestTy->isPtrOrPtrVectorTy() ||
+      SrcTy->isVectorTy() != DestTy->isVectorTy()) {
+    return;
+  }
+
+  unsigned SrcAS = SrcTy->getPointerAddressSpace();
+  unsigned DstAS = DestTy->getPointerAddressSpace();
+
+  unsigned SrcASSize = DL->getPointerSizeInBits(SrcAS);
+  unsigned DstASSize = DL->getPointerSizeInBits(DstAS);
+  Assert1(SrcASSize == DstASSize,
+          "Bitcasts between pointers of different address spaces must have "
+          "the same size pointers, otherwise use PtrToInt/IntToPtr.", V);
+}
+
+void Verifier::VerifyConstantExprBitcastType(const ConstantExpr *CE) {
+  if (CE->getOpcode() == Instruction::BitCast) {
+    Type *SrcTy = CE->getOperand(0)->getType();
+    Type *DstTy = CE->getType();
+    VerifyBitcastType(CE, DstTy, SrcTy);
+  }
+}
+
 bool Verifier::VerifyAttributeCount(AttributeSet Attrs, unsigned Params) {
   if (Attrs.getNumSlots() == 0)
     return true;
@@ -1349,26 +1429,9 @@ void Verifier::visitIntToPtrInst(IntToPt
 }
 
 void Verifier::visitBitCastInst(BitCastInst &I) {
-  // Get the source and destination types
   Type *SrcTy = I.getOperand(0)->getType();
   Type *DestTy = I.getType();
-
-  // Get the size of the types in bits, we'll need this later
-  unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
-  unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
-
-  // BitCast implies a no-op cast of type only. No bits change.
-  // However, you can't cast pointers to anything but pointers.
-  Assert1(SrcTy->isPointerTy() == DestTy->isPointerTy(),
-          "Bitcast requires both operands to be pointer or neither", &I);
-  Assert1(SrcBitSize == DestBitSize, "Bitcast requires types of same width",&I);
-
-  // Disallow aggregates.
-  Assert1(!SrcTy->isAggregateType(),
-          "Bitcast operand must not be aggregate", &I);
-  Assert1(!DestTy->isAggregateType(),
-          "Bitcast type must not be aggregate", &I);
-
+  VerifyBitcastType(&I, DestTy, SrcTy);
   visitInstruction(I);
 }
 
@@ -1992,6 +2055,27 @@ void Verifier::visitInstruction(Instruct
       Assert1((i + 1 == e && isa<CallInst>(I)) ||
               (i + 3 == e && isa<InvokeInst>(I)),
               "Cannot take the address of an inline asm!", &I);
+    } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(i))) {
+      if (CE->getType()->isPtrOrPtrVectorTy()) {
+        // If we have a ConstantExpr pointer, we need to see if it came from an
+        // illegal bitcast (inttoptr <constant int> )
+        SmallVector<const ConstantExpr *, 4> Stack;
+        SmallPtrSet<const ConstantExpr *, 4> Visited;
+        Stack.push_back(CE);
+
+        while (!Stack.empty()) {
+          const ConstantExpr *V = Stack.pop_back_val();
+          if (!Visited.insert(V))
+            continue;
+
+          VerifyConstantExprBitcastType(V);
+
+          for (unsigned I = 0, N = V->getNumOperands(); I != N; ++I) {
+            if (ConstantExpr *Op = dyn_cast<ConstantExpr>(V->getOperand(I)))
+              Stack.push_back(Op);
+          }
+        }
+      }
     }
   }
 

Added: llvm/trunk/test/Verifier/bitcast-address-space-nested-global-cycle.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/bitcast-address-space-nested-global-cycle.ll?rev=187506&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/bitcast-address-space-nested-global-cycle.ll (added)
+++ llvm/trunk/test/Verifier/bitcast-address-space-nested-global-cycle.ll Wed Jul 31 12:49:08 2013
@@ -0,0 +1,8 @@
+; RUN: not llvm-as -verify -disable-output %s
+
+target datalayout = "e-p:32:32:32-p1:16:16:16-p2:8:8:8-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n8:16:32"
+
+%struct.Self1 = type { %struct.Self1 addrspace(1)* }
+
+ at cycle1 = addrspace(1) constant %struct.Self1 { %struct.Self1 addrspace(1)* bitcast (%struct.Self1 addrspace(0)* @cycle0 to %struct.Self1 addrspace(1)*) }
+ at cycle0 = addrspace(0) constant %struct.Self1 { %struct.Self1 addrspace(1)* @cycle1 }

Added: llvm/trunk/test/Verifier/bitcast-address-space-nested-global.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/bitcast-address-space-nested-global.ll?rev=187506&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/bitcast-address-space-nested-global.ll (added)
+++ llvm/trunk/test/Verifier/bitcast-address-space-nested-global.ll Wed Jul 31 12:49:08 2013
@@ -0,0 +1,11 @@
+; RUN: not llvm-as -verify -disable-output %s
+
+target datalayout = "e-p:32:32:32-p1:16:16:16-p2:8:8:8-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n8:16:32"
+
+
+%struct.Self1 = type { %struct.Self1 addrspace(1)* }
+
+ at nestedD = constant %struct.Self1 { %struct.Self1 addrspace(1)* bitcast (%struct.Self1 addrspace(0)* @nestedC to %struct.Self1 addrspace(1)*) }
+ at nestedC = constant %struct.Self1 { %struct.Self1 addrspace(1)* bitcast (%struct.Self1 addrspace(0)* @nestedB to %struct.Self1 addrspace(1)*) }
+ at nestedB = constant %struct.Self1 { %struct.Self1 addrspace(1)* bitcast (%struct.Self1 addrspace(0)* @nestedA to %struct.Self1 addrspace(1)*) }
+ at nestedA = constant %struct.Self1 { %struct.Self1 addrspace(1)* null }

Added: llvm/trunk/test/Verifier/bitcast-address-space-through-constant-inttoptr-inside-gep-instruction.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/bitcast-address-space-through-constant-inttoptr-inside-gep-instruction.ll?rev=187506&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/bitcast-address-space-through-constant-inttoptr-inside-gep-instruction.ll (added)
+++ llvm/trunk/test/Verifier/bitcast-address-space-through-constant-inttoptr-inside-gep-instruction.ll Wed Jul 31 12:49:08 2013
@@ -0,0 +1,10 @@
+; RUN: not llvm-as -verify -disable-output < %s
+target datalayout = "e-p:32:32:32-p1:16:16:16-p2:8:8:8-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n8:16:32"
+
+; Check that we can find inttoptr -> illegal bitcasts when hidden
+; inside constantexpr pointer operands
+define i32 addrspace(2)* @illegal_bitcast_inttoptr_as_1_to_2_inside_gep() {
+  %cast = getelementptr i32 addrspace(2)* bitcast (i32 addrspace(1)* inttoptr (i32 1234 to i32 addrspace(1)*) to i32 addrspace(2)*), i32 3
+  ret i32 addrspace(2)* %cast
+}
+

Added: llvm/trunk/test/Verifier/bitcast-address-space-through-constant-inttoptr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/bitcast-address-space-through-constant-inttoptr.ll?rev=187506&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/bitcast-address-space-through-constant-inttoptr.ll (added)
+++ llvm/trunk/test/Verifier/bitcast-address-space-through-constant-inttoptr.ll Wed Jul 31 12:49:08 2013
@@ -0,0 +1,11 @@
+; RUN: not llvm-as -verify -disable-output %s
+
+target datalayout = "e-p:32:32:32-p1:16:16:16-p2:8:8:8-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n8:16:32"
+
+
+%struct.Foo = type { i32 addrspace(1)* }
+
+; Make sure we still reject the bitcast when the source is a inttoptr (constant int) in a global initializer
+ at bitcast_after_constant_inttoptr_initializer = global %struct.Foo { i32 addrspace(1)* bitcast (i32 addrspace(2)* inttoptr (i8 7 to i32 addrspace(2)*) to i32 addrspace(1)*) }
+
+

Added: llvm/trunk/test/Verifier/bitcast-address-space-through-gep-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/bitcast-address-space-through-gep-2.ll?rev=187506&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/bitcast-address-space-through-gep-2.ll (added)
+++ llvm/trunk/test/Verifier/bitcast-address-space-through-gep-2.ll Wed Jul 31 12:49:08 2013
@@ -0,0 +1,17 @@
+; RUN: not llvm-as -verify -disable-output %s
+
+target datalayout = "e-p:32:32:32-p1:16:16:16-p2:8:8:8-p3:8:8:8-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n8:16:32"
+
+
+%struct.Foo1 = type { i32 addrspace(1)* }
+
+ at as2_array = addrspace(2) global [32 x i32] zeroinitializer
+
+; gep -> legal bitcast (2 -> 3) -> gep -> illegal bitcast (3 -> 1)
+ at bitcast_after_gep_bitcast_gep =
+         global %struct.Foo1 { i32 addrspace(1)* bitcast
+                                    (i32 addrspace(3)* getelementptr
+                                         (i32 addrspace(3)* bitcast
+                                              (i32 addrspace(2)* getelementptr
+                                                   ([32 x i32] addrspace(2)* @as2_array, i32 0, i32 8) to i32 addrspace(3)*), i32 3) to i32 addrspace(1)*) }
+

Added: llvm/trunk/test/Verifier/bitcast-address-space-through-gep.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/bitcast-address-space-through-gep.ll?rev=187506&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/bitcast-address-space-through-gep.ll (added)
+++ llvm/trunk/test/Verifier/bitcast-address-space-through-gep.ll Wed Jul 31 12:49:08 2013
@@ -0,0 +1,13 @@
+; RUN: not llvm-as -verify -disable-output %s
+
+target datalayout = "e-p:32:32:32-p1:16:16:16-p2:8:8:8-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n8:16:32"
+
+%struct.Foo = type { i32 addrspace(1)* }
+
+
+ at as2_array = addrspace(2) global [32 x i32] zeroinitializer
+
+; Make sure we still reject the bitcast after the value is accessed through a GEP
+ at bitcast_after_gep = global %struct.Foo { i32 addrspace(1)* bitcast (i32 addrspace(2)* getelementptr ([32 x i32] addrspace(2)* @as2_array, i32 0, i32 8) to i32 addrspace(1)*) }
+
+

Added: llvm/trunk/test/Verifier/bitcast-address-space-through-inttoptr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/bitcast-address-space-through-inttoptr.ll?rev=187506&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/bitcast-address-space-through-inttoptr.ll (added)
+++ llvm/trunk/test/Verifier/bitcast-address-space-through-inttoptr.ll Wed Jul 31 12:49:08 2013
@@ -0,0 +1,9 @@
+; RUN: not llvm-as -verify -disable-output %s
+
+target datalayout = "e-p:32:32:32-p1:16:16:16-p2:8:8:8-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n8:16:32"
+
+define i32 addrspace(2)* @illegal_bitcast_as_1_to_2_inttoptr() {
+   %cast = bitcast i32 addrspace(1)* inttoptr (i32 5 to i32 addrspace(1)*) to i32 addrspace(2)*
+   ret i32 addrspace(2)* %cast
+}
+

Added: llvm/trunk/test/Verifier/bitcast-address-spaces.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/bitcast-address-spaces.ll?rev=187506&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/bitcast-address-spaces.ll (added)
+++ llvm/trunk/test/Verifier/bitcast-address-spaces.ll Wed Jul 31 12:49:08 2013
@@ -0,0 +1,9 @@
+; RUN: not llvm-as -verify -disable-output %s
+
+target datalayout = "e-p:32:32:32-p1:16:16:16-p2:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n8:16:32"
+
+define i32 addrspace(1)* @illegal_bitcast_as_0_to_1(i32 addrspace(0) *%p) {
+  %cast = bitcast i32 addrspace(0)* %p to i32 addrspace(1)*
+  ret i32 addrspace(1)* %cast
+}
+

Added: llvm/trunk/test/Verifier/bitcast-vector-pointer-as.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/bitcast-vector-pointer-as.ll?rev=187506&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/bitcast-vector-pointer-as.ll (added)
+++ llvm/trunk/test/Verifier/bitcast-vector-pointer-as.ll Wed Jul 31 12:49:08 2013
@@ -0,0 +1,9 @@
+; RUN: not llvm-as -verify -disable-output %s
+
+target datalayout = "e-p:32:32:32-p1:16:16:16-p2:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n8:16:32"
+
+define <4 x i32 addrspace(1)*> @vector_illegal_bitcast_as_0_to_1(<4 x i32 addrspace(0)*> %p) {
+   %cast = bitcast <4 x i32 addrspace(0)*> %p to <4 x i32 addrspace(1)*>
+   ret <4 x i32 addrspace(1)*> %cast
+}
+





More information about the llvm-commits mailing list