@@ -474,52 +474,60 @@ void Lists::createListTypeAssumption(const LLVMListPtr &listPtr, llvm::Value *ty
474474 llvm::Value *boolType = m_builder.getInt32 (static_cast <uint32_t >(ValueType::Bool));
475475 llvm::Value *stringType = m_builder.getInt32 (static_cast <uint32_t >(ValueType::String));
476476
477- // Number
478- llvm::BasicBlock *noNumberBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " listTypeAssumption.noNumber " , m_utils.function ());
479- llvm::BasicBlock *afterNoNumberBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " listTypeAssumption.afterNoNumber " , m_utils.function ());
480- m_builder. CreateCondBr (hasNumber, afterNoNumberBlock, noNumberBlock );
477+ // Create assumptions
478+ llvm::BasicBlock *outOfRangeBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " outOfRange " , m_utils.function ());
479+ llvm::BasicBlock *inRangeBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " inRange " , m_utils.function ());
480+ llvm::BasicBlock *afterBlock = llvm::BasicBlock::Create (m_utils. llvmCtx (), " afterAssume " , m_utils. function () );
481481
482- m_builder.SetInsertPoint (noNumberBlock);
483- llvm::Value *isNotNumber = m_builder.CreateICmpNE (type, numberType);
484- m_builder.CreateCall (assumeIntrinsic, isNotNumber);
485- m_builder.CreateBr (afterNoNumberBlock);
482+ m_builder.CreateCondBr (inRange, inRangeBlock, outOfRangeBlock);
486483
487- m_builder.SetInsertPoint (afterNoNumberBlock);
484+ // In-range assumptions
485+ m_builder.SetInsertPoint (inRangeBlock);
488486
489- // Bool
490- llvm::BasicBlock *noBoolBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " listTypeAssumption.noBool" , m_utils.function ());
491- llvm::BasicBlock *afterNoBoolBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " listTypeAssumption.afterNoBool" , m_utils.function ());
492- m_builder.CreateCondBr (hasBool, afterNoBoolBlock, noBoolBlock);
487+ auto assume = [&](llvm::Value *cond) { m_builder.CreateCall (assumeIntrinsic, cond); };
493488
494- m_builder.SetInsertPoint (noBoolBlock);
495- llvm::Value *isNotBool = m_builder.CreateICmpNE (type, boolType);
496- m_builder.CreateCall (assumeIntrinsic, isNotBool);
497- m_builder.CreateBr (afterNoBoolBlock);
489+ llvm::Value *notNumber = m_builder.CreateNot (hasNumber);
490+ llvm::Value *notBool = m_builder.CreateNot (hasBool);
491+ llvm::Value *notString = m_builder.CreateNot (hasString);
498492
499- m_builder.SetInsertPoint (afterNoBoolBlock);
493+ // if (!hasBool && !hasString) type == Number
494+ llvm::Value *cond1 = m_builder.CreateAnd (notBool, notString);
495+ llvm::Value *assume1 = m_builder.CreateICmpEQ (type, numberType);
496+ assume (m_builder.CreateSelect (cond1, assume1, m_builder.getInt1 (true )));
500497
501- // String
502- llvm::BasicBlock *noStringBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " listTypeAssumption.noString" , m_utils.function ());
503- llvm::BasicBlock *afterNoStringBlock = llvm::BasicBlock::Create (m_utils.llvmCtx (), " listTypeAssumption.afterNoString" , m_utils.function ());
498+ // else if (!hasNumber && !hasString) type == Bool
499+ llvm::Value *cond2 = m_builder.CreateAnd (notNumber, notString);
500+ llvm::Value *assume2 = m_builder.CreateICmpEQ (type, boolType);
501+ assume (m_builder.CreateSelect (cond2, assume2, m_builder.getInt1 (true )));
504502
505- if (inRange)
506- m_builder.CreateCondBr (m_builder. CreateAnd (m_builder. CreateNot (hasString), inRange), noStringBlock, afterNoStringBlock );
507- else
508- m_builder.CreateCondBr (hasString, afterNoStringBlock, noStringBlock );
503+ // else if (!hasNumber && !hasBool) type == String
504+ llvm::Value *cond3 = m_builder.CreateAnd (notNumber, notBool );
505+ llvm::Value *assume3 = m_builder. CreateICmpEQ (type, stringType);
506+ assume ( m_builder.CreateSelect (cond3, assume3, m_builder. getInt1 ( true )) );
509507
510- m_builder. SetInsertPoint (noStringBlock);
511- llvm::Value *isNotString = m_builder. CreateICmpNE (type, stringType) ;
512- m_builder.CreateCall (assumeIntrinsic, isNotString );
513- m_builder.CreateBr (afterNoStringBlock );
508+ // else if (!hasBool) type == Number || type == String
509+ llvm::Value *cond4 = notBool ;
510+ llvm::Value *assume4 = m_builder.CreateOr (m_builder. CreateICmpEQ (type, numberType), m_builder. CreateICmpEQ (type, stringType) );
511+ assume ( m_builder.CreateSelect (cond4, assume4, m_builder. getInt1 ( true )) );
514512
515- m_builder.SetInsertPoint (afterNoStringBlock);
513+ // else if (!hasNumber) type == Bool || type == String
514+ llvm::Value *cond5 = notNumber;
515+ llvm::Value *assume5 = m_builder.CreateOr (m_builder.CreateICmpEQ (type, boolType), m_builder.CreateICmpEQ (type, stringType));
516+ assume (m_builder.CreateSelect (cond5, assume5, m_builder.getInt1 (true )));
516517
517- if (inRange) {
518- llvm::Value *stringType = m_builder.getInt32 (static_cast <uint32_t >(ValueType::String));
519- llvm::Value *canNotBeString = m_builder.CreateNot (hasString);
520- llvm::Value *isString = m_builder.CreateICmpEQ (type, stringType);
521- llvm::Value *impossible = m_builder.CreateAnd (m_builder.CreateAnd (inRange, canNotBeString), isString);
522- m_builder.CreateCall (assumeIntrinsic, m_builder.CreateNot (impossible));
523- }
518+ // else if (!hasString) type == Number || type == Bool
519+ llvm::Value *cond6 = notString;
520+ llvm::Value *assume6 = m_builder.CreateOr (m_builder.CreateICmpEQ (type, numberType), m_builder.CreateICmpEQ (type, boolType));
521+ assume (m_builder.CreateSelect (cond6, assume6, m_builder.getInt1 (true )));
522+
523+ m_builder.CreateBr (afterBlock);
524+
525+ // Out-of-range: always string
526+ m_builder.SetInsertPoint (outOfRangeBlock);
527+ llvm::Value *isString = m_builder.CreateICmpEQ (type, stringType);
528+ assume (isString);
529+ m_builder.CreateBr (afterBlock);
530+
531+ m_builder.SetInsertPoint (afterBlock);
524532 }
525533}
0 commit comments