Skip to content

Commit 1c043a9

Browse files
committedOct 24, 2017
[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 llvm-svn: 316430
1 parent e1285e3 commit 1c043a9

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed
 

‎llvm/lib/IR/ConstantFold.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,15 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
629629
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
630630
if (CE->getOpcode() == Instruction::GetElementPtr &&
631631
CE->getOperand(0)->isNullValue()) {
632+
// FIXME: Looks like getFoldedSizeOf(), getFoldedOffsetOf() and
633+
// getFoldedAlignOf() don't handle the case when DestTy is a vector of
634+
// pointers yet. We end up in asserts in CastInst::getCastOpcode (see
635+
// test/Analysis/ConstantFolding/cast-vector.ll). I've only seen this
636+
// happen in one "real" C-code test case, so it does not seem to be an
637+
// important optimization to handle vectors here. For now, simply bail
638+
// out.
639+
if (DestTy->isVectorTy())
640+
return nullptr;
632641
GEPOperator *GEPO = cast<GEPOperator>(CE);
633642
Type *Ty = GEPO->getSourceElementType();
634643
if (CE->getNumOperands() == 2) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -instsimplify -S | FileCheck %s
3+
4+
; Test constant fold of constant expression GEP used by ptrtoint (the
5+
; "offsetof-like expression" case).
6+
; This used to hit an assert due to not supporting vectors in
7+
; llvm::ConstantFoldCastInstruction when handling ptrtoint.
8+
define <2 x i16> @test1() {
9+
; CHECK-LABEL: @test1(
10+
; CHECK-NEXT: entry:
11+
; 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>)
12+
;
13+
entry:
14+
%gep = getelementptr inbounds [10 x i32], [10 x i32]* null, i16 0, <2 x i16> <i16 5, i16 7>
15+
%vec = ptrtoint <2 x i32*> %gep to <2 x i16>
16+
ret <2 x i16> %vec
17+
}
18+
19+
; Test constant fold of constant expression GEP used by ptrtoint (the
20+
; "sizeof-like expression" case).
21+
; This used to hit an assert due to not supporting vectors in
22+
; llvm::ConstantFoldCastInstruction when handling ptrtoint.
23+
define <2 x i16> @test2() {
24+
; CHECK-LABEL: @test2(
25+
; CHECK-NEXT: entry:
26+
; 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>)
27+
;
28+
entry:
29+
%gep = getelementptr i32, i32* null, <2 x i16> <i16 5, i16 7>
30+
%vec = ptrtoint <2 x i32*> %gep to <2 x i16>
31+
ret <2 x i16> %vec
32+
}

0 commit comments

Comments
 (0)
Please sign in to comment.