@@ -70,6 +70,75 @@ static std::string PrintType(const Type *type, bool truncate = false) {
7070 return s;
7171}
7272
73+ static bool
74+ isNonTrivialBitcast (const Instruction &inst,
75+ lldb_private::ExecutionContext &exe_ctx) {
76+ auto *result_type = dyn_cast<VectorType>(inst.getType ());
77+ auto *operand = inst.getOperand (0 );
78+ auto *operand_type = dyn_cast<VectorType>(operand->getType ());
79+
80+ // If neither type is a vector then the bitcast is trivial
81+ if (!result_type && !operand_type)
82+ return false ;
83+
84+ // Get endianness and element order from the architecture
85+ lldb::ByteOrder byte_order = lldb::eByteOrderLittle;
86+ lldb::ByteOrder element_order = lldb::eByteOrderLittle;
87+
88+ lldb::TargetSP target_sp = exe_ctx.GetTargetSP ();
89+ if (target_sp) {
90+ const auto *arch_plugin = target_sp->GetArchitecturePlugin ();
91+ if (arch_plugin) {
92+ byte_order = target_sp->GetArchitecture ().GetByteOrder ();
93+ element_order = arch_plugin->GetVectorElementOrder ();
94+ }
95+ }
96+
97+ // Bitcast is trivial if endianness matches element order
98+ if (byte_order == element_order)
99+ return false ;
100+
101+ // If the element order and value byte order disagree then vector bitcasts
102+ // aren't no-ops when the element sizes change. For example given:
103+ // <2 x i32> <i32 0x00112233, i32 0x44556677>
104+ // then bitcast's LangRef definition of
105+ // store <2 x i32>, ptr @loc
106+ // load <4 x i16>, ptr @loc
107+ // gives:
108+ // Order | Mem after Store | <4 x i16> after Load | Bitcast
109+ // LF | 3322110077665544 | 0x3322 0x0011 0x6677 0x4455 | no-op
110+ // BN | 0011223344556677 | 0x0011 0x2233 0x4455 0x6677 | shuffle
111+ // LF | 7766554433221100 | 0x6677 0x4455 0x3322 0x1100 | shuffle
112+ // BN | 4455667700112233 | 0x4455 0x6677 0x0011 0x2233 | no-op
113+ // Order abbreviations:
114+ // L = Little Endian
115+ // B = Big Endian
116+ // F = Lane 0 is first
117+ // N = Lane N-1 is first
118+
119+ // If only one type is a vector, then we'll assume it's non-trivial on the
120+ // basis that this changes the number of elements from N to 1 or the other
121+ // way around.
122+ if (!result_type || !operand_type)
123+ return false ;
124+
125+ // I'm not sure how scalable vectors behave in this situation.
126+ // Reject them to be safe.
127+ if (!result_type->getElementCount ().isFixed () ||
128+ !operand_type->getElementCount ().isFixed ())
129+ return true ;
130+
131+ // We can handle the cases that are no-op by virtue of the element
132+ // sizes/counts not changing but the shuffle cases aren't
133+ // implemented in IRInterpreter::Interpret so decline to interpret
134+ // them.
135+ if (result_type->getElementCount () != operand_type->getElementCount () ||
136+ result_type->getScalarSizeInBits () != operand_type->getScalarSizeInBits ())
137+ return true ;
138+
139+ return false ;
140+ }
141+
73142static bool CanIgnoreCall (const CallInst *call) {
74143 const llvm::Function *called_function = call->getCalledFunction ();
75144
@@ -367,7 +436,62 @@ class InterpreterStackFrame {
367436 return true ;
368437 }
369438
439+ bool ResolveVectorConstant (lldb::addr_t process_address,
440+ const Constant *constant) {
441+ auto *vector_type = dyn_cast<FixedVectorType>(constant->getType ());
442+ if (!vector_type)
443+ return false ;
444+
445+ Type *element_type = vector_type->getElementType ();
446+ unsigned num_elements = vector_type->getNumElements ();
447+ size_t element_size = m_target_data.getTypeStoreSize (element_type);
448+ size_t total_size = element_size * num_elements;
449+
450+ lldb_private::DataBufferHeap buf (total_size, 0 );
451+ uint8_t *data_ptr = buf.GetBytes ();
452+
453+ if (isa<ConstantAggregateZero>(constant)) {
454+ // Zero initializer - buffer is already zeroed, just write it
455+ lldb_private::Status write_error;
456+ m_execution_unit.WriteMemory (process_address, buf.GetBytes (),
457+ buf.GetByteSize (), write_error);
458+ return write_error.Success ();
459+ }
460+
461+ if (const ConstantDataVector *cdv =
462+ dyn_cast<ConstantDataVector>(constant)) {
463+ for (unsigned i = 0 ; i < num_elements; ++i) {
464+ const Constant *element = cdv->getElementAsConstant (i);
465+ APInt element_value;
466+ if (!ResolveConstantValue (element_value, element))
467+ return false ;
468+
469+ size_t offset = i * element_size;
470+
471+ lldb_private::Scalar element_scalar (
472+ element_value.zextOrTrunc (element_size * 8 ));
473+ lldb_private::Status get_data_error;
474+ if (!element_scalar.GetAsMemoryData (data_ptr + offset, element_size,
475+ m_byte_order, get_data_error))
476+ return false ;
477+ }
478+ lldb_private::Status write_error;
479+ m_execution_unit.WriteMemory (process_address, buf.GetBytes (),
480+ buf.GetByteSize (), write_error);
481+
482+ return write_error.Success ();
483+ }
484+
485+ return false ;
486+ }
487+
370488 bool ResolveConstant (lldb::addr_t process_address, const Constant *constant) {
489+ // Handle vector constants specially since they can't be represented as a
490+ // single APInt
491+ if (constant->getType ()->isVectorTy ()) {
492+ return ResolveVectorConstant (process_address, constant);
493+ }
494+
371495 APInt resolved_value;
372496
373497 if (!ResolveConstantValue (resolved_value, constant))
@@ -484,8 +608,12 @@ static bool CanResolveConstant(llvm::Constant *constant) {
484608 return false ;
485609 case Value::ConstantIntVal:
486610 case Value::ConstantFPVal:
611+ return true ;
487612 case Value::FunctionVal:
488613 return true ;
614+ case Value::ConstantDataVectorVal:
615+ case Value::ConstantAggregateZeroVal:
616+ return constant->getType ()->getTypeID () == Type::FixedVectorTyID;
489617 case Value::ConstantExprVal:
490618 if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
491619 switch (constant_expr->getOpcode ()) {
@@ -522,7 +650,8 @@ static bool CanResolveConstant(llvm::Constant *constant) {
522650
523651bool IRInterpreter::CanInterpret (llvm::Module &module , llvm::Function &function,
524652 lldb_private::Status &error,
525- const bool support_function_calls) {
653+ const bool support_function_calls,
654+ lldb_private::ExecutionContext &exe_ctx) {
526655 lldb_private::Log *log (GetLog (LLDBLog::Expressions));
527656
528657 bool saw_function_with_body = false ;
@@ -548,9 +677,13 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
548677 }
549678 case Instruction::Add:
550679 case Instruction::Alloca:
551- case Instruction::BitCast:
552680 case Instruction::Br:
553681 case Instruction::PHI:
682+ case Instruction::ExtractElement:
683+ break ;
684+ case Instruction::BitCast:
685+ if (isNonTrivialBitcast (ii, exe_ctx))
686+ return false ;
554687 break ;
555688 case Instruction::Call: {
556689 CallInst *call_inst = dyn_cast<CallInst>(&ii);
@@ -645,6 +778,7 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
645778 default :
646779 break ;
647780 case Type::FixedVectorTyID:
781+ break ;
648782 case Type::ScalableVectorTyID: {
649783 LLDB_LOGF (log, " Unsupported operand type: %s" ,
650784 PrintType (operand_type).c_str ());
@@ -657,8 +791,9 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,
657791 // The IR interpreter currently doesn't know about
658792 // 128-bit integers. As they're not that frequent,
659793 // we can just fall back to the JIT rather than
660- // choking.
661- if (operand_type->getPrimitiveSizeInBits () > 64 ) {
794+ // choking. However, allow vectors since we handle them above.
795+ if (operand_type->getPrimitiveSizeInBits () > 64 &&
796+ !operand_type->isVectorTy ()) {
662797 LLDB_LOGF (log, " Unsupported operand type: %s" ,
663798 PrintType (operand_type).c_str ());
664799 error =
@@ -1543,9 +1678,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
15431678 // Void return type
15441679 if (returnType->isVoidTy ()) {
15451680 // Cant assign to void types, so we leave the frame untouched
1546- } else
1547- // Integer or pointer return type
1548- if (returnType->isIntegerTy () || returnType->isPointerTy ()) {
1681+ } else if (returnType->isIntegerTy () || returnType->isPointerTy ()) {
15491682 // Get the encapsulated return value
15501683 lldb::ValueObjectSP retVal = call_plan_sp.get ()->GetReturnValueObject ();
15511684
@@ -1567,10 +1700,113 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
15671700 frame.AssignValue (inst, returnVal, module );
15681701 }
15691702 } break ;
1703+ case Instruction::ExtractElement: {
1704+ if (!InterpretExtractElement (inst, frame, data_layout, module ,
1705+ execution_unit, error, log))
1706+ return false ;
1707+ } break ;
15701708 }
15711709
15721710 ++frame.m_ii ;
15731711 }
15741712
15751713 return false ;
15761714}
1715+
1716+ bool IRInterpreter::InterpretExtractElement (
1717+ const llvm::Instruction *inst, InterpreterStackFrame &frame,
1718+ const llvm::DataLayout &data_layout, llvm::Module &module ,
1719+ lldb_private::IRExecutionUnit &execution_unit, lldb_private::Status &error,
1720+ lldb_private::Log *log) {
1721+ const ExtractElementInst *extract_inst = cast<ExtractElementInst>(inst);
1722+
1723+ // Get the vector and index operands
1724+ const Value *vector_operand = extract_inst->getVectorOperand ();
1725+ const Value *index_operand = extract_inst->getIndexOperand ();
1726+
1727+ // Get the vector address
1728+ lldb::addr_t vector_addr =
1729+ frame.ResolveValue (vector_operand, module );
1730+
1731+ if (vector_addr == LLDB_INVALID_ADDRESS) {
1732+ LLDB_LOGF (log, " ExtractElement's vector doesn't resolve to anything" );
1733+ error = lldb_private::Status::FromErrorString (bad_value_error);
1734+ return false ;
1735+ }
1736+
1737+ // Evaluate the index
1738+ lldb_private::Scalar index_scalar;
1739+ if (!frame.EvaluateValue (index_scalar, index_operand, module )) {
1740+ LLDB_LOGF (log, " Couldn't evaluate index %s" ,
1741+ PrintValue (index_operand).c_str ());
1742+ error = lldb_private::Status::FromErrorString (bad_value_error);
1743+ return false ;
1744+ }
1745+
1746+ uint64_t index = index_scalar.ULongLong ();
1747+
1748+ // Get the vector type information
1749+ auto *vector_type = dyn_cast<FixedVectorType>(vector_operand->getType ());
1750+ if (!vector_type) {
1751+ LLDB_LOGF (log, " ExtractElement instruction doesn't have a fixed vector "
1752+ " operand type" );
1753+ error = lldb_private::Status::FromErrorString (interpreter_internal_error);
1754+ return false ;
1755+ }
1756+
1757+ unsigned num_elements = vector_type->getNumElements ();
1758+ if (index >= num_elements) {
1759+ LLDB_LOG (log,
1760+ " ExtractElement index {0} is out of bounds for vector with "
1761+ " {1} elements" ,
1762+ index, num_elements);
1763+ error = lldb_private::Status::FromErrorString (bad_value_error);
1764+ return false ;
1765+ }
1766+
1767+ Type *element_type = vector_type->getElementType ();
1768+ size_t element_size = data_layout.getTypeStoreSize (element_type);
1769+
1770+ size_t element_offset = index * element_size;
1771+
1772+ // Allocate space for the result element
1773+ lldb::addr_t result_addr = frame.ResolveValue (extract_inst, module );
1774+ if (result_addr == LLDB_INVALID_ADDRESS) {
1775+ LLDB_LOG (log, " ExtractElement's result doesn't resolve to anything" );
1776+ error = lldb_private::Status::FromErrorString (bad_value_error);
1777+ return false ;
1778+ }
1779+
1780+ // Read the element from the vector
1781+ lldb_private::DataBufferHeap element_buffer (element_size, 0 );
1782+ lldb_private::Status read_error;
1783+ execution_unit.ReadMemory (element_buffer.GetBytes (),
1784+ vector_addr + element_offset, element_size,
1785+ read_error);
1786+ if (!read_error.Success ()) {
1787+ LLDB_LOG (log, " Couldn't read element data for ExtractElement" );
1788+ error = lldb_private::Status::FromErrorString (memory_read_error);
1789+ return false ;
1790+ }
1791+
1792+ // Write the element to the result location
1793+ lldb_private::Status write_error;
1794+ execution_unit.WriteMemory (result_addr, element_buffer.GetBytes (),
1795+ element_size, write_error);
1796+ if (!write_error.Success ()) {
1797+ LLDB_LOG (log, " Couldn't write result for ExtractElement" );
1798+ error = lldb_private::Status::FromErrorString (memory_write_error);
1799+ return false ;
1800+ }
1801+
1802+ if (log) {
1803+ LLDB_LOG (log,
1804+ " Interpreted an ExtractElement\n "
1805+ " Vector: {0}\n "
1806+ " Index: {1}\n "
1807+ " Element offset: {2}\n "
1808+ " Result: {3}\n " ,
1809+ vector_addr, index, element_offset, result_addr);
1810+ }
1811+ return true ;
1812+ }
0 commit comments