Skip to content

Commit

Permalink
[IR Verifier] Do not allow bitcast of pointer to vector of pointers a…
Browse files Browse the repository at this point in the history
…nd vice versa.

LangRef for BitCast requires that
"The bit sizes of value and the destination type, ty2, must be identical".
Currently verifier allows BitCast of pointer to vector of pointers so that
the sizes are different.

This change fixes that.

Reviewers: arsenm
Reviewed By: arsenm
Subscribers: llvm-commits, wdng
Differential Revision: https://reviews.llvm.org/D50886

llvm-svn: 340249
  • Loading branch information
Serguei Katkov committed Aug 21, 2018
1 parent efef49c commit 09ab506
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 6 deletions.
14 changes: 8 additions & 6 deletions llvm/lib/IR/Instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2978,12 +2978,14 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, Type *DstTy) {
return false;

// A vector of pointers must have the same number of elements.
if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) {
if (VectorType *DstVecTy = dyn_cast<VectorType>(DstTy))
return (SrcVecTy->getNumElements() == DstVecTy->getNumElements());

return false;
}
VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy);
VectorType *DstVecTy = dyn_cast<VectorType>(DstTy);
if (SrcVecTy && DstVecTy)
return (SrcVecTy->getNumElements() == DstVecTy->getNumElements());
if (SrcVecTy)
return SrcVecTy->getNumElements() == 1;
if (DstVecTy)
return DstVecTy->getNumElements() == 1;

return true;
}
Expand Down
10 changes: 10 additions & 0 deletions llvm/test/Verifier/bitcast-pointer-vector-neg.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
; RUN: not llvm-as -disable-output %s 2>&1 | FileCheck %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"

; CHECK: error: invalid cast opcode for cast from 'i64*' to '<2 x i32*>'

define <2 x i32*> @illegal_bitcast_pointer_to_vector_of_pointers(i64* %a) {
%b = bitcast i64* %a to <2 x i32*>
ret <2 x i32*> %b
}
15 changes: 15 additions & 0 deletions llvm/test/Verifier/bitcast-vector-pointer-as-neg.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
; RUN: not llvm-as -disable-output %s 2>&1 | FileCheck %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"

; CHECK: error: invalid cast opcode for cast from '<4 x i32 addrspace(1)*>' to '<2 x i32 addrspace(2)*>'

; The pointer in addrspace 1 of the size 16 while pointer in addrspace 2 of the size 32.
; Converting 4 element array of pointers from addrspace 2 to 2 element array in addrspace 2
; has the same total bit length but bitcast still does not allow conversion into
; different addrspace.
define <2 x i32 addrspace(2)*> @vector_illegal_bitcast_as_1_to_2(<4 x i32 addrspace(1)*> %p) {
%cast = bitcast <4 x i32 addrspace(1)*> %p to <2 x i32 addrspace(2)*>
ret <2 x i32 addrspace(2)*> %cast
}

10 changes: 10 additions & 0 deletions llvm/test/Verifier/bitcast-vector-pointer-neg.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
; RUN: not llvm-as -disable-output %s 2>&1 | FileCheck %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"

; CHECK: error: invalid cast opcode for cast from '<2 x i32*>' to 'i64*'

define i64* @illegal_bitcast_vector_of_pointers_to_pointer(<2 x i32*> %a) {
%b = bitcast <2 x i32*> %a to i64*
ret i64* %b
}
14 changes: 14 additions & 0 deletions llvm/test/Verifier/bitcast-vector-pointer-pos.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
; RUN: llvm-as -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 <1 x i32*> @vector_legal_bitcast_pointer_to_vector_of_pointers(i64* %a) {
%b = bitcast i64* %a to <1 x i32*>
ret <1 x i32*> %b
}

define i64* @vector_legal_bitcast_vector_of_pointers_to_pointer(<1 x i32*> %a) {
%b = bitcast <1 x i32*> %a to i64*
ret i64* %b
}

0 comments on commit 09ab506

Please sign in to comment.