Skip to content

Commit ace386e

Browse files
authored
Merge branch 'main' into users/rampitec/09-18-_amdgpu_gfx1251_vop2_dpp_support
2 parents 344bfe1 + e3c7b7f commit ace386e

26 files changed

+698
-225
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ Improvements to Clang's diagnostics
265265
- Fixed fix-it hint for fold expressions. Clang now correctly places the suggested right
266266
parenthesis when diagnosing malformed fold expressions. (#GH151787)
267267
- Added fix-it hint for when scoped enumerations require explicit conversions for binary operations. (#GH24265)
268-
268+
- Constant template parameters are now type checked in template definitions,
269+
including template template parameters.
269270
- Fixed an issue where emitted format-signedness diagnostics were not associated with an appropriate
270271
diagnostic id. Besides being incorrect from an API standpoint, this was user visible, e.g.:
271272
"format specifies type 'unsigned int' but the argument has type 'int' [-Wformat]"

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5482,9 +5482,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
54825482
if (NTTP->isParameterPack() && NTTP->isExpandedParameterPack())
54835483
NTTPType = NTTP->getExpansionType(ArgumentPackIndex);
54845484

5485-
if (NTTPType->isInstantiationDependentType() &&
5486-
!isa<TemplateTemplateParmDecl>(Template) &&
5487-
!Template->getDeclContext()->isDependentContext()) {
5485+
if (NTTPType->isInstantiationDependentType()) {
54885486
// Do substitution on the type of the non-type template parameter.
54895487
InstantiatingTemplate Inst(*this, TemplateLoc, Template, NTTP,
54905488
CTAI.SugaredConverted,
@@ -5494,6 +5492,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
54945492

54955493
MultiLevelTemplateArgumentList MLTAL(Template, CTAI.SugaredConverted,
54965494
/*Final=*/true);
5495+
MLTAL.addOuterRetainedLevels(NTTP->getDepth());
54975496
// If the parameter is a pack expansion, expand this slice of the pack.
54985497
if (auto *PET = NTTPType->getAs<PackExpansionType>()) {
54995498
Sema::ArgPackSubstIndexRAII SubstIndex(*this, ArgumentPackIndex);

clang/test/SemaTemplate/temp_arg_template.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,8 @@ namespace CheckDependentNonTypeParamTypes {
117117
X<int, long, 3> x;
118118
}
119119
void h() {
120-
// FIXME: If we accept A<B> at all, it's not obvious what should happen
121-
// here. While parsing the template, we form
122-
// X<unsigned char, int, (unsigned char)1234>
123-
// but in the final instantiation do we get
124-
// B<unsigned char, int, (int)1234>
125-
// or
126-
// B<unsigned char, int, (int)(unsigned char)1234>
127-
// ?
128120
X<unsigned char, int, 1234> x;
129-
int check[x.value == 1234 ? 1 : -1];
121+
// expected-error@-1 {{evaluates to 1234, which cannot be narrowed to type 'unsigned char'}}
130122
}
131123
};
132124

@@ -143,6 +135,20 @@ namespace CheckDependentNonTypeParamTypes {
143135
ab.g();
144136
ab.h();
145137
}
138+
139+
template<class> struct C {
140+
template<class T, T V> struct D {};
141+
using T = D<char, 1234>;
142+
// expected-error@-1 {{evaluates to 1234, which cannot be narrowed to type 'char'}}
143+
};
144+
145+
template<class T> struct E {
146+
template <template <T V> class TT> struct F {
147+
using X = TT<1234>;
148+
};
149+
};
150+
// FIXME: This should be rejected, as there are no valid instantiations for E<char>::F
151+
template struct E<char>;
146152
}
147153

148154
namespace PR32185 {

lldb/include/lldb/Core/Opcode.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,9 @@ class Opcode {
223223
int Dump(Stream *s, uint32_t min_byte_width) const;
224224

225225
const void *GetOpcodeBytes() const {
226-
return ((m_type == Opcode::eTypeBytes) ? m_data.inst.bytes : nullptr);
226+
return ((m_type == Opcode::eTypeBytes || m_type == Opcode::eType16_32Tuples)
227+
? m_data.inst.bytes
228+
: nullptr);
227229
}
228230

229231
uint32_t GetByteSize() const {

lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp

Lines changed: 164 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionRISCV, InstructionRISCV)
3333

3434
namespace lldb_private {
3535

36+
// RISC-V General Purpose Register numbers
37+
static constexpr uint32_t RISCV_GPR_SP = 2; // x2 is the stack pointer
38+
static constexpr uint32_t RISCV_GPR_FP = 8; // x8 is the frame pointer
39+
3640
/// Returns all values wrapped in Optional, or std::nullopt if any of the values
3741
/// is std::nullopt.
3842
template <typename... Ts>
@@ -108,6 +112,16 @@ static uint32_t FPREncodingToLLDB(uint32_t reg_encode) {
108112
return LLDB_INVALID_REGNUM;
109113
}
110114

115+
// Helper function to get register info from GPR encoding
116+
static std::optional<RegisterInfo>
117+
GPREncodingToRegisterInfo(EmulateInstructionRISCV &emulator,
118+
uint32_t reg_encode) {
119+
uint32_t lldb_reg = GPREncodingToLLDB(reg_encode);
120+
if (lldb_reg == LLDB_INVALID_REGNUM)
121+
return std::nullopt;
122+
return emulator.GetRegisterInfo(eRegisterKindLLDB, lldb_reg);
123+
}
124+
111125
bool Rd::Write(EmulateInstructionRISCV &emulator, uint64_t value) {
112126
uint32_t lldb_reg = GPREncodingToLLDB(rd);
113127
EmulateInstruction::Context ctx;
@@ -230,10 +244,34 @@ Load(EmulateInstructionRISCV &emulator, I inst, uint64_t (*extend)(E)) {
230244
auto addr = LoadStoreAddr(emulator, inst);
231245
if (!addr)
232246
return false;
233-
return transformOptional(
234-
emulator.ReadMem<T>(*addr),
235-
[&](T t) { return inst.rd.Write(emulator, extend(E(t))); })
236-
.value_or(false);
247+
248+
// Set up context for the load operation, similar to ARM64.
249+
EmulateInstructionRISCV::Context context;
250+
251+
// Get register info for base register
252+
std::optional<RegisterInfo> reg_info_rs1 =
253+
GPREncodingToRegisterInfo(emulator, inst.rs1.rs);
254+
255+
if (!reg_info_rs1)
256+
return false;
257+
258+
// Set context type based on whether this is a stack-based load.
259+
if (inst.rs1.rs == RISCV_GPR_SP)
260+
context.type = EmulateInstruction::eContextPopRegisterOffStack;
261+
else
262+
context.type = EmulateInstruction::eContextRegisterLoad;
263+
264+
// Set the context address information
265+
context.SetAddress(*addr);
266+
267+
// Read from memory with context and write to register.
268+
bool success = false;
269+
uint64_t value =
270+
emulator.ReadMemoryUnsigned(context, *addr, sizeof(T), 0, &success);
271+
if (!success)
272+
return false;
273+
274+
return inst.rd.Write(emulator, extend(E(T(value))));
237275
}
238276

239277
template <typename I, typename T>
@@ -242,9 +280,35 @@ Store(EmulateInstructionRISCV &emulator, I inst) {
242280
auto addr = LoadStoreAddr(emulator, inst);
243281
if (!addr)
244282
return false;
245-
return transformOptional(
246-
inst.rs2.Read(emulator),
247-
[&](uint64_t rs2) { return emulator.WriteMem<T>(*addr, rs2); })
283+
284+
// Set up context for the store operation, similar to ARM64.
285+
EmulateInstructionRISCV::Context context;
286+
287+
// Get register info for source and base registers.
288+
std::optional<RegisterInfo> reg_info_rs1 =
289+
GPREncodingToRegisterInfo(emulator, inst.rs1.rs);
290+
std::optional<RegisterInfo> reg_info_rs2 =
291+
GPREncodingToRegisterInfo(emulator, inst.rs2.rs);
292+
293+
if (!reg_info_rs1 || !reg_info_rs2)
294+
return false;
295+
296+
// Set context type based on whether this is a stack-based store.
297+
if (inst.rs1.rs == RISCV_GPR_SP)
298+
context.type = EmulateInstruction::eContextPushRegisterOnStack;
299+
else
300+
context.type = EmulateInstruction::eContextRegisterStore;
301+
302+
// Set the context to show which register is being stored to which base
303+
// register + offset.
304+
context.SetRegisterToRegisterPlusOffset(*reg_info_rs2, *reg_info_rs1,
305+
SignExt(inst.imm));
306+
307+
return transformOptional(inst.rs2.Read(emulator),
308+
[&](uint64_t rs2) {
309+
return emulator.WriteMemoryUnsigned(
310+
context, *addr, rs2, sizeof(T));
311+
})
248312
.value_or(false);
249313
}
250314

@@ -737,11 +801,44 @@ class Executor {
737801
bool operator()(SH inst) { return Store<SH, uint16_t>(m_emu, inst); }
738802
bool operator()(SW inst) { return Store<SW, uint32_t>(m_emu, inst); }
739803
bool operator()(ADDI inst) {
740-
return transformOptional(inst.rs1.ReadI64(m_emu),
741-
[&](int64_t rs1) {
742-
return inst.rd.Write(
743-
m_emu, rs1 + int64_t(SignExt(inst.imm)));
744-
})
804+
return transformOptional(
805+
inst.rs1.ReadI64(m_emu),
806+
[&](int64_t rs1) {
807+
int64_t result = rs1 + int64_t(SignExt(inst.imm));
808+
// Check if this is a stack pointer adjustment.
809+
if (inst.rd.rd == RISCV_GPR_SP &&
810+
inst.rs1.rs == RISCV_GPR_SP) {
811+
EmulateInstruction::Context context;
812+
context.type =
813+
EmulateInstruction::eContextAdjustStackPointer;
814+
context.SetImmediateSigned(SignExt(inst.imm));
815+
uint32_t sp_lldb_reg = GPREncodingToLLDB(RISCV_GPR_SP);
816+
RegisterValue registerValue;
817+
registerValue.SetUInt64(result);
818+
return m_emu.WriteRegister(context, eRegisterKindLLDB,
819+
sp_lldb_reg, registerValue);
820+
}
821+
// Check if this is setting up the frame pointer.
822+
// addi fp, sp, imm -> fp = sp + imm (frame pointer setup).
823+
if (inst.rd.rd == RISCV_GPR_FP &&
824+
inst.rs1.rs == RISCV_GPR_SP) {
825+
EmulateInstruction::Context context;
826+
context.type = EmulateInstruction::eContextSetFramePointer;
827+
auto sp_reg_info = m_emu.GetRegisterInfo(
828+
eRegisterKindLLDB, GPREncodingToLLDB(RISCV_GPR_SP));
829+
if (sp_reg_info) {
830+
context.SetRegisterPlusOffset(*sp_reg_info,
831+
SignExt(inst.imm));
832+
}
833+
uint32_t fp_lldb_reg = GPREncodingToLLDB(RISCV_GPR_FP);
834+
RegisterValue registerValue;
835+
registerValue.SetUInt64(result);
836+
return m_emu.WriteRegister(context, eRegisterKindLLDB,
837+
fp_lldb_reg, registerValue);
838+
}
839+
// Regular ADDI instruction.
840+
return inst.rd.Write(m_emu, result);
841+
})
745842
.value_or(false);
746843
}
747844
bool operator()(SLTI inst) {
@@ -1745,6 +1842,61 @@ EmulateInstructionRISCV::GetRegisterInfo(RegisterKind reg_kind,
17451842
return array[reg_index];
17461843
}
17471844

1845+
bool EmulateInstructionRISCV::SetInstruction(const Opcode &opcode,
1846+
const Address &inst_addr,
1847+
Target *target) {
1848+
// Call the base class implementation.
1849+
if (!EmulateInstruction::SetInstruction(opcode, inst_addr, target))
1850+
return false;
1851+
1852+
// Extract instruction data from the opcode.
1853+
uint32_t inst_data = 0;
1854+
const void *opcode_data = m_opcode.GetOpcodeBytes();
1855+
if (!opcode_data)
1856+
return false;
1857+
1858+
if (m_opcode.GetByteSize() == 2) {
1859+
// 16-bit compressed instruction.
1860+
const uint16_t *data = static_cast<const uint16_t *>(opcode_data);
1861+
inst_data = *data;
1862+
} else if (m_opcode.GetByteSize() == 4) {
1863+
// 32-bit instruction.
1864+
const uint32_t *data = static_cast<const uint32_t *>(opcode_data);
1865+
inst_data = *data;
1866+
} else {
1867+
return false;
1868+
}
1869+
1870+
// Decode the instruction.
1871+
auto decoded_inst = Decode(inst_data);
1872+
if (!decoded_inst)
1873+
return false;
1874+
1875+
// Store the decoded result.
1876+
m_decoded = *decoded_inst;
1877+
return true;
1878+
}
1879+
1880+
bool EmulateInstructionRISCV::CreateFunctionEntryUnwind(
1881+
UnwindPlan &unwind_plan) {
1882+
unwind_plan.Clear();
1883+
unwind_plan.SetRegisterKind(eRegisterKindLLDB);
1884+
1885+
UnwindPlan::Row row;
1886+
1887+
row.GetCFAValue().SetIsRegisterPlusOffset(gpr_sp_riscv, 0);
1888+
row.SetRegisterLocationToSame(gpr_ra_riscv, /*must_replace=*/false);
1889+
row.SetRegisterLocationToSame(gpr_fp_riscv, /*must_replace=*/false);
1890+
1891+
unwind_plan.AppendRow(std::move(row));
1892+
unwind_plan.SetSourceName("EmulateInstructionRISCV");
1893+
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1894+
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
1895+
unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1896+
unwind_plan.SetReturnAddressRegister(gpr_ra_riscv);
1897+
return true;
1898+
}
1899+
17481900
bool EmulateInstructionRISCV::SetTargetTriple(const ArchSpec &arch) {
17491901
return SupportsThisArch(arch);
17501902
}

lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class EmulateInstructionRISCV : public EmulateInstruction {
6161
case eInstructionTypePCModifying:
6262
return true;
6363
case eInstructionTypePrologueEpilogue:
64+
return true;
6465
case eInstructionTypeAll:
6566
return false;
6667
}
@@ -85,6 +86,7 @@ class EmulateInstructionRISCV : public EmulateInstruction {
8586
return SupportsThisInstructionType(inst_type);
8687
}
8788

89+
bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) override;
8890
bool SetTargetTriple(const ArchSpec &arch) override;
8991
bool ReadInstruction() override;
9092
std::optional<uint32_t> GetLastInstrSize() override { return m_last_size; }
@@ -94,6 +96,8 @@ class EmulateInstructionRISCV : public EmulateInstruction {
9496
std::optional<RegisterInfo> GetRegisterInfo(lldb::RegisterKind reg_kind,
9597
uint32_t reg_num) override;
9698

99+
bool SetInstruction(const Opcode &opcode, const Address &inst_addr,
100+
Target *target) override;
97101
std::optional<DecodeResult> ReadInstructionAt(lldb::addr_t addr);
98102
std::optional<DecodeResult> Decode(uint32_t inst);
99103
bool Execute(DecodeResult inst, bool ignore_cond);

lldb/unittests/Instruction/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@ add_lldb_unittest(EmulatorTests
22
ARM64/TestAArch64Emulator.cpp
33
LoongArch/TestLoongArchEmulator.cpp
44
RISCV/TestRISCVEmulator.cpp
5+
RISCV/TestRiscvInstEmulation.cpp
56

67
LINK_COMPONENTS
78
Support
9+
${LLVM_TARGETS_TO_BUILD}
810
LINK_LIBS
911
lldbCore
1012
lldbSymbol
1113
lldbTarget
1214
lldbPluginInstructionARM64
1315
lldbPluginInstructionLoongArch
1416
lldbPluginInstructionRISCV
17+
lldbPluginDisassemblerLLVMC
18+
lldbPluginUnwindAssemblyInstEmulation
19+
lldbPluginProcessUtility
1520
)

0 commit comments

Comments
 (0)