[ConstantFolding] Avoid assert when folding ptrtoint of vectorized GEP

Summary:
Got asserts in llvm::CastInst::getCastOpcode saying:
`DestBits == SrcBits && "Illegal cast to vector (wrong type or size)"' failed.

Problem seemed to be that llvm::ConstantFoldCastInstruction did
not handle ptrtoint cast of a getelementptr returning a vector
correctly. I assume such situations are quite rare, since the
GEP needs to be considered as a constant value (base pointer
being null).
The solution used here is to simply avoid the constant fold
of ptrtoint when the value is a vector. It is not supported,
and by bailing out we do not fail on assertions later on.

Reviewers: craig.topper, majnemer, davide, filcab, efriedma

Reviewed By: efriedma

Subscribers: efriedma, filcab, llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316430 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bjorn Pettersson 2017-10-24 12:08:11 +00:00
parent 7b97ca1b57
commit e1bccd3b6e
2 changed files with 41 additions and 0 deletions

View File

@ -629,6 +629,15 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
if (CE->getOpcode() == Instruction::GetElementPtr &&
CE->getOperand(0)->isNullValue()) {
// FIXME: Looks like getFoldedSizeOf(), getFoldedOffsetOf() and
// getFoldedAlignOf() don't handle the case when DestTy is a vector of
// pointers yet. We end up in asserts in CastInst::getCastOpcode (see
// test/Analysis/ConstantFolding/cast-vector.ll). I've only seen this
// happen in one "real" C-code test case, so it does not seem to be an
// important optimization to handle vectors here. For now, simply bail
// out.
if (DestTy->isVectorTy())
return nullptr;
GEPOperator *GEPO = cast<GEPOperator>(CE);
Type *Ty = GEPO->getSourceElementType();
if (CE->getNumOperands() == 2) {

View File

@ -0,0 +1,32 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instsimplify -S | FileCheck %s
; Test constant fold of constant expression GEP used by ptrtoint (the
; "offsetof-like expression" case).
; This used to hit an assert due to not supporting vectors in
; llvm::ConstantFoldCastInstruction when handling ptrtoint.
define <2 x i16> @test1() {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret <2 x i16> ptrtoint (<2 x i32*> getelementptr ([10 x i32], [10 x i32]* null, <2 x i64> zeroinitializer, <2 x i64> <i64 5, i64 7>) to <2 x i16>)
;
entry:
%gep = getelementptr inbounds [10 x i32], [10 x i32]* null, i16 0, <2 x i16> <i16 5, i16 7>
%vec = ptrtoint <2 x i32*> %gep to <2 x i16>
ret <2 x i16> %vec
}
; Test constant fold of constant expression GEP used by ptrtoint (the
; "sizeof-like expression" case).
; This used to hit an assert due to not supporting vectors in
; llvm::ConstantFoldCastInstruction when handling ptrtoint.
define <2 x i16> @test2() {
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret <2 x i16> ptrtoint (<2 x i32*> getelementptr (i32, i32* null, <2 x i64> <i64 5, i64 7>) to <2 x i16>)
;
entry:
%gep = getelementptr i32, i32* null, <2 x i16> <i16 5, i16 7>
%vec = ptrtoint <2 x i32*> %gep to <2 x i16>
ret <2 x i16> %vec
}