diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -47,6 +47,11 @@ if (CV->isAllOnesValue()) return Constant::getAllOnesValue(DstTy); if (CV->isNullValue()) return Constant::getNullValue(DstTy); + // Do not iterate on scalable vector. The num of elements is unknown at + // compile-time. + if (DstTy->isScalable()) + return nullptr; + // If this cast changes element count then we can't handle it here: // doing so requires endianness information. This should be handled by // Analysis/ConstantFolding.cpp @@ -563,6 +568,28 @@ if (isAllNull) // This is casting one pointer type to another, always BitCast return ConstantExpr::getPointerCast(CE->getOperand(0), DestTy); + } else if (CE->getOpcode() == Instruction::ShuffleVector && + opc == Instruction::BitCast) { + // For splat vector, fold bitcast to splat value. + // BitCast(ShuffleVector(InsertElement(Undef, C, Zero), V, Zero)) to NewType + // into + // ShuffleVector(InsertElement(Undef, BitCast(C) to NewType, Zero), V, Zero) + Constant *SplatV; + if (match(CE, + m_ShuffleVector( + m_InsertElement(m_Undef(), m_Constant(SplatV), m_Zero()), + m_Value(), m_Zero()))) { + auto NewCast = + ConstantExpr::getCast(opc, SplatV, DestTy->getScalarType()); + auto InsertElem = CE->getOperand(0); + auto NewInsertElem = ConstantExpr::getInsertElement( + UndefValue::get(DestTy), NewCast, + cast(InsertElem->getOperand(2))); + return ConstantExpr::getShuffleVector( + NewInsertElem, + ConstantExpr::getCast(opc, CE->getOperand(1), DestTy), + CE->getOperand(2)); + } } } diff --git a/llvm/test/Analysis/ConstantFolding/bitcast.ll b/llvm/test/Analysis/ConstantFolding/bitcast.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/ConstantFolding/bitcast.ll @@ -0,0 +1,12 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -constprop -S -verify | FileCheck %s + +define @bitcast_scalable_constant() { +; CHECK-LABEL: @bitcast_scalable_constant( +; CHECK-NEXT: ret shufflevector ( insertelement ( undef, float 0x36A0000000000000, i32 0), undef, zeroinitializer) +; + %i1 = insertelement undef, i32 1, i32 0 + %i2 = shufflevector %i1, undef, zeroinitializer + %i3 = bitcast %i2 to + ret %i3 +}