From 749ddd25e901c5214222be0e8e7be47424e5fdfe Mon Sep 17 00:00:00 2001 From: guopeilin Date: Sat, 11 Sep 2021 18:50:30 +0800 Subject: [PATCH] [BitcodeReader] Delay select until all constants resolved Like the shuffle, we should treat the select delayed so that all constants can be resolved. Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D109053 --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 50 +++++++++++++++------- .../Bitcode/bitcode-parseconstant-delay-select.ll | 13 ++++++ 2 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 llvm/test/Bitcode/bitcode-parseconstant-delay-select.ll diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 6aad83e..c339418 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2355,6 +2355,15 @@ Error BitcodeReader::parseConstants() { unsigned CstNo; }; std::vector DelayedShuffles; + struct DelayedSelTy { + Type *OpTy; + uint64_t Op0Idx; + uint64_t Op1Idx; + uint64_t Op2Idx; + unsigned CstNo; + }; + std::vector DelayedSelectors; + while (true) { Expected MaybeEntry = Stream.advanceSkippingSubblocks(); if (!MaybeEntry) @@ -2391,6 +2400,27 @@ Error BitcodeReader::parseConstants() { Value *V = ConstantExpr::getShuffleVector(Op0, Op1, Mask); ValueList.assignValue(V, CstNo); } + for (auto &DelayedSelector : DelayedSelectors) { + Type *OpTy = DelayedSelector.OpTy; + Type *SelectorTy = Type::getInt1Ty(Context); + uint64_t Op0Idx = DelayedSelector.Op0Idx; + uint64_t Op1Idx = DelayedSelector.Op1Idx; + uint64_t Op2Idx = DelayedSelector.Op2Idx; + uint64_t CstNo = DelayedSelector.CstNo; + Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy); + Constant *Op2 = ValueList.getConstantFwdRef(Op2Idx, OpTy); + // The selector might be an i1 or an + // Get the type from the ValueList before getting a forward ref. + if (VectorType *VTy = dyn_cast(OpTy)) { + Value *V = ValueList[Op0Idx]; + assert(V); + if (SelectorTy != V->getType()) + SelectorTy = VectorType::get(SelectorTy, VTy->getElementCount()); + } + Constant *Op0 = ValueList.getConstantFwdRef(Op0Idx, SelectorTy); + Value *V = ConstantExpr::getSelect(Op0, Op1, Op2); + ValueList.assignValue(V, CstNo); + } if (NextCstNo != ValueList.size()) return error("Invalid constant reference"); @@ -2687,21 +2717,11 @@ Error BitcodeReader::parseConstants() { if (Record.size() < 3) return error("Invalid record"); - Type *SelectorTy = Type::getInt1Ty(Context); - - // The selector might be an i1, an , or a - // Get the type from the ValueList before getting a forward ref. - if (VectorType *VTy = dyn_cast(CurTy)) - if (Value *V = ValueList[Record[0]]) - if (SelectorTy != V->getType()) - SelectorTy = VectorType::get(SelectorTy, - VTy->getElementCount()); - - V = ConstantExpr::getSelect(ValueList.getConstantFwdRef(Record[0], - SelectorTy), - ValueList.getConstantFwdRef(Record[1],CurTy), - ValueList.getConstantFwdRef(Record[2],CurTy)); - break; + DelayedSelectors.push_back( + {CurTy, Record[0], Record[1], Record[2], NextCstNo}); + (void)ValueList.getConstantFwdRef(NextCstNo, CurTy); + ++NextCstNo; + continue; } case bitc::CST_CODE_CE_EXTRACTELT : { // CE_EXTRACTELT: [opty, opval, opty, opval] diff --git a/llvm/test/Bitcode/bitcode-parseconstant-delay-select.ll b/llvm/test/Bitcode/bitcode-parseconstant-delay-select.ll new file mode 100644 index 0000000..8845a27 --- /dev/null +++ b/llvm/test/Bitcode/bitcode-parseconstant-delay-select.ll @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s -preserve-bc-uselistorder=false | llvm-dis -disable-output +@a = external dso_local global i32, align 4 +@c = external dso_local global [3 x i32], align 4 +@b = external dso_local local_unnamed_addr global i32, align 4 + +define dso_local i32 @main() local_unnamed_addr { +middle.block: + br label %for.cond.for.end_crit_edge + +for.cond.for.end_crit_edge: ; preds = %middle.block + store i32 extractelement (<4 x i32> select (<4 x i1> select (<4 x i1> , <4 x i1> , <4 x i1> zeroinitializer), <4 x i32> zeroinitializer, <4 x i32> select (<4 x i1> select (<4 x i1> , <4 x i1> , <4 x i1> zeroinitializer), <4 x i32> , <4 x i32> )), i32 3), i32* @b, align 4 + ret i32 undef +} -- 2.7.4