Index: llvm/trunk/lib/IR/ConstantFold.cpp =================================================================== --- llvm/trunk/lib/IR/ConstantFold.cpp +++ llvm/trunk/lib/IR/ConstantFold.cpp @@ -629,6 +629,15 @@ if (ConstantExpr *CE = dyn_cast(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(CE); Type *Ty = GEPO->getSourceElementType(); if (CE->getNumOperands() == 2) { Index: llvm/trunk/test/Analysis/ConstantFolding/cast-vector.ll =================================================================== --- llvm/trunk/test/Analysis/ConstantFolding/cast-vector.ll +++ llvm/trunk/test/Analysis/ConstantFolding/cast-vector.ll @@ -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> ) to <2 x i16>) +; +entry: + %gep = getelementptr inbounds [10 x i32], [10 x i32]* null, i16 0, <2 x i16> + %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> ) to <2 x i16>) +; +entry: + %gep = getelementptr i32, i32* null, <2 x i16> + %vec = ptrtoint <2 x i32*> %gep to <2 x i16> + ret <2 x i16> %vec +}