@@ -290,17 +290,40 @@ LLVMInstruction *Lists::buildGetListItem(LLVMInstruction *ins)
290290 llvm::Value *size = m_utils.getListSize (listPtr);
291291 size = m_builder.CreateUIToFP (size, m_builder.getDoubleTy ());
292292 llvm::Value *index = m_utils.castValue (arg.second , arg.first );
293- llvm::Value *inRange = m_builder.CreateAnd (m_builder.CreateFCmpOGE (index, min), m_builder.CreateFCmpOLT (index, size), " inRange " );
293+ llvm::Value *inRange = m_builder.CreateAnd (m_builder.CreateFCmpOGE (index, min), m_builder.CreateFCmpOLT (index, size), " getListItem.indexInRange " );
294294
295- LLVMConstantRegister nullReg (Compiler::StaticType::String, " " );
296- llvm::Value *null = m_utils.createValue (static_cast <LLVMRegister *>(&nullReg));
295+ llvm::BasicBlock *inRangeBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " getListItem.inRange" , m_utils.function ());
296+ llvm::BasicBlock *outOfRangeBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " getListItem.outOfRange" , m_utils.function ());
297+ llvm::BasicBlock *nextBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " getListItem.next" , m_utils.function ());
298+ m_builder.CreateCondBr (inRange, inRangeBlock, outOfRangeBlock);
297299
300+ // In range
301+ m_builder.SetInsertPoint (inRangeBlock);
298302 index = m_builder.CreateFPToUI (index, m_builder.getInt64Ty ());
303+ llvm::Value *itemPtr = m_utils.getListItem (listPtr, index);
304+ llvm::Value *itemType = m_builder.CreateLoad (m_builder.getInt32Ty (), m_utils.getValueTypePtr (itemPtr));
305+ m_builder.CreateBr (nextBlock);
306+
307+ // Out of range
308+ m_builder.SetInsertPoint (outOfRangeBlock);
309+ LLVMConstantRegister emptyStringReg (Compiler::StaticType::String, " " );
310+ llvm::Value *emptyString = m_utils.createValue (static_cast <LLVMRegister *>(&emptyStringReg));
311+ llvm::Value *stringType = m_builder.getInt32 (static_cast <uint32_t >(ValueType::String));
312+ m_builder.CreateBr (nextBlock);
299313
300- llvm::Value *itemPtr = m_builder.CreateSelect (inRange, m_utils.getListItem (listPtr, index), null);
301- llvm::Value *typeVar = createListTypeVar (listPtr, itemPtr, inRange);
314+ m_builder.SetInsertPoint (nextBlock);
315+
316+ // Result
317+ llvm::PHINode *result = m_builder.CreatePHI (itemPtr->getType (), 2 , " getListItem.result" );
318+ result->addIncoming (itemPtr, inRangeBlock);
319+ result->addIncoming (emptyString, outOfRangeBlock);
302320
303- ins->functionReturnReg ->value = itemPtr;
321+ llvm::PHINode *itemTypeResult = m_builder.CreatePHI (m_builder.getInt32Ty (), 2 , " getListItem.itemType" );
322+ itemTypeResult->addIncoming (itemType, inRangeBlock);
323+ itemTypeResult->addIncoming (stringType, outOfRangeBlock);
324+
325+ llvm::Value *typeVar = createListTypeVar (listPtr, itemTypeResult);
326+ ins->functionReturnReg ->value = result;
304327 ins->functionReturnReg ->typeVar = typeVar;
305328 createListTypeAssumption (listPtr, typeVar, ins->targetType , inRange);
306329
@@ -396,36 +419,10 @@ void Lists::createListTypeUpdate(const LLVMListPtr &listPtr, const LLVMRegister
396419 }
397420}
398421
399- llvm::Value *Lists::createListTypeVar (const LLVMListPtr &listPtr, llvm::Value *itemPtr, llvm::Value *inRange )
422+ llvm::Value *Lists::createListTypeVar (const LLVMListPtr &listPtr, llvm::Value *type )
400423{
401424 llvm::Value *typeVar = m_utils.addAlloca (m_builder.getInt32Ty ());
402- llvm::BasicBlock *inRangeBlock = nullptr ;
403- llvm::BasicBlock *outOfRangeBlock = nullptr ;
404- llvm::BasicBlock *nextBlock = nullptr ;
405-
406- if (inRange) {
407- inRangeBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " " , m_utils.function ());
408- outOfRangeBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " " , m_utils.function ());
409- nextBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " " , m_utils.function ());
410-
411- m_builder.CreateCondBr (inRange, inRangeBlock, outOfRangeBlock);
412- m_builder.SetInsertPoint (inRangeBlock);
413- }
414-
415- llvm::Value *type = m_builder.CreateLoad (m_builder.getInt32Ty (), m_utils.getValueTypePtr (itemPtr));
416425 m_builder.CreateStore (type, typeVar);
417-
418- if (inRange) {
419- m_builder.CreateBr (nextBlock);
420- m_builder.SetInsertPoint (outOfRangeBlock);
421-
422- llvm::Value *type = m_builder.getInt32 (static_cast <uint32_t >(ValueType::String));
423- m_builder.CreateStore (type, typeVar);
424- m_builder.CreateBr (nextBlock);
425-
426- m_builder.SetInsertPoint (nextBlock);
427- }
428-
429426 return typeVar;
430427}
431428
0 commit comments