@@ -83,7 +83,7 @@ bool load_to(const llvm::LoadInst* load) {
83
83
return detail::get_operand_to<T>(load).has_value ();
84
84
}
85
85
86
- std::optional<llvm::DIType*> reset_load_related_basic (const dataflow::ValuePath&, llvm::DIType* type_to_reset,
86
+ std::optional<llvm::DIType*> reset_load_related_basic (const dataflow::ValuePath& path , llvm::DIType* type_to_reset,
87
87
const llvm::LoadInst* load) {
88
88
auto * type = type_to_reset;
89
89
@@ -101,6 +101,25 @@ std::optional<llvm::DIType*> reset_load_related_basic(const dataflow::ValuePath&
101
101
return type;
102
102
}
103
103
104
+ // a (last?) load to a GEP of a composite likely loads the first member in an optimized context:
105
+ const bool last_load = path.start_value ().value_or (nullptr ) == load;
106
+ if (last_load && load_to<llvm::GetElementPtrInst>(load)) {
107
+ if (auto * may_be_member_type = llvm::dyn_cast<llvm::DIDerivedType>(type)) {
108
+ LOG_DEBUG (" Load on GEP, return basetype " << log ::ditype_str (may_be_member_type->getBaseType ()))
109
+ if (di::util::is_member (*may_be_member_type)) {
110
+ auto type_of_member = may_be_member_type->getBaseType ();
111
+ if (auto member = llvm::dyn_cast<llvm::DIDerivedType>(type_of_member)) {
112
+ may_be_member_type = member;
113
+ if (auto * member_composite_type = llvm::dyn_cast<llvm::DICompositeType>(member->getBaseType ())) {
114
+ auto members_of_composite_type = di::util::get_composite_members (*member_composite_type);
115
+ assert (members_of_composite_type.size () > 0 && " Load to composite expects at least one member" );
116
+ return (*members_of_composite_type.begin ());
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+
104
123
if (auto * maybe_ptr_to_type = llvm::dyn_cast<llvm::DIDerivedType>(type)) {
105
124
if (di::util::is_pointer (*maybe_ptr_to_type)) {
106
125
LOG_DEBUG (" Load of pointer-like " << log ::ditype_str (maybe_ptr_to_type))
0 commit comments