From 050445151c7a3ea19c84e0535c45fdf6f45eb164 Mon Sep 17 00:00:00 2001 From: Kevin Quick Date: Tue, 2 Jan 2024 11:18:04 -0800 Subject: [PATCH] Adds a new C++ test, with associated known_bugs entry for current failure. --- disasm-test/known_bugs/p2.cpp | 10 ++ disasm-test/tests/p2.cpp | 268 ++++++++++++++++++++++++++++++++++ disasm-test/tests/p2.ll | 239 ++++++++++++++++++++++++++++++ 3 files changed, 517 insertions(+) create mode 100644 disasm-test/known_bugs/p2.cpp create mode 100644 disasm-test/tests/p2.cpp create mode 100644 disasm-test/tests/p2.ll diff --git a/disasm-test/known_bugs/p2.cpp b/disasm-test/known_bugs/p2.cpp new file mode 100644 index 00000000..7aec33c9 --- /dev/null +++ b/disasm-test/known_bugs/p2.cpp @@ -0,0 +1,10 @@ +##> rootMatchName: p2.cpp +##> summary: failure to llvm-as the llvm-disasm results + +Using this module's llvm-disasm to convert the clang++ generated bitcode into assembly (.ll), the resulting assembly is invalid for llvm-as: + + error: expected type + define linkonce_ddr default i32 @_ZN4uorb14uorb_advertiseEPK21orb_metadata(%class.uorb* %32 + +This is demonstrated with llvm version 7, 11, 13, and 15: it may or may not occur +with other LLVM versions. diff --git a/disasm-test/tests/p2.cpp b/disasm-test/tests/p2.cpp new file mode 100644 index 00000000..865b165c --- /dev/null +++ b/disasm-test/tests/p2.cpp @@ -0,0 +1,268 @@ +/* This is the p1 demo but modified to make uorb a class and the uorb + * interaction via methods and not functions. + */ + +#include + + +#define UORB_DEFINE(name) \ + const struct orb_metadata name = { #name }; + +struct orb_metadata { + char * name; +}; + +/* uORB */ + +class uorb { +public: + + /* Subscribe to a topic described by the metadata + + Returns a handle (file descriptor) that can be polled to + determine when messages are available + */ + int uorb_subscribe(const struct orb_metadata * o) { return 1; } + + /* Unsubscribe from the given topic */ + void uorb_unsubscribe(const struct orb_metadata * o) {} + + /* Atomically publish data to the topic */ + int uorb_publish(const struct orb_metadata * o, const void *data) { return 0; } + + /* Copy a message off of the handle returned by `uorb_subscribe` */ + int uorb_copy(const struct orb_metadata * o, int handle, void *buffer) { return 0; } + + /* Declare that this component publishes to this channel */ + int uorb_advertise(const struct orb_metadata * o) { return 0; } +} + main_uorb; + +UORB_DEFINE(vehicle_gps); +UORB_DEFINE(gyro); +UORB_DEFINE(battery_status); +UORB_DEFINE(vehicle_status); +UORB_DEFINE(manual_setpoint); +UORB_DEFINE(actuator_controls); +UORB_DEFINE(angular_velocity); +UORB_DEFINE(trigger); +UORB_DEFINE(camera_capture); + +/* Vehicle GPS */ +struct gps_status { + double lat; + double lon; +}; + +void vehicle_gps_start() { + main_uorb.uorb_advertise(&vehicle_gps); +} + +void vehicle_gps_update() { + struct gps_status stat; + main_uorb.uorb_publish(&vehicle_gps, &stat); +} + +void vehicle_gps_stop() {} + +/* Vehicle Angular Acceleration */ +struct angular_accel { + double accel; +}; +int vehicle_angular_acc_handle; +void vehicle_angular_acc_start() { + vehicle_angular_acc_handle = main_uorb.uorb_subscribe(&gyro); + main_uorb.uorb_advertise(&angular_velocity); +} + +void vehicle_angular_acc_stop() { + main_uorb.uorb_unsubscribe(&gyro); +} + +struct gyro_status { + double angleX; + double angleY; + double angleZ; +}; + +void compute_angular_accel(struct gyro_status *stat, struct angular_accel *msg) { + msg->accel = 100 * stat->angleX + stat->angleY - stat->angleZ; +} + +// The vehicle angular accelerator update function that is called in the periodic update loop +void vehicle_angular_acc_update() { + // Pull inputs from the message bus + struct gyro_status stat; + main_uorb.uorb_copy(&gyro, vehicle_angular_acc_handle, &stat); + + // Compute a message to send based on those inputs + struct angular_accel msg; + compute_angular_accel(&stat, &msg); + main_uorb.uorb_publish(&angular_velocity, &msg); +} + +/* Gyro Sensor */ +void gyro_start() { + main_uorb.uorb_advertise(&gyro); +} + +void read_gyro(struct gyro_status *stat) { + volatile double * getX = (double*)0x555550; + volatile double * getY = (double*)0x555560; + volatile double * getZ = (double*)0x555570; + stat->angleX = *getX; + stat->angleY = *getY; + stat->angleZ = *getZ; +} + +int gyro_calc_inconsistency(struct gyro_status *stat) { + if(rand() < 100) return 1; + else return 0; +} + +void gyro_update() { + struct gyro_status stat; + read_gyro(&stat); + if(!gyro_calc_inconsistency(&stat)) + main_uorb.uorb_publish(&gyro, &stat); +} + + +/* Fixedwing Attitude Control */ +struct actuator_control { + int mode; + double pitch; + double yaw; +}; + +int fw_att_control_handle; +void fw_att_control_start() { + fw_att_control_handle = main_uorb.uorb_subscribe(&angular_velocity); + main_uorb.uorb_advertise(&actuator_controls); +} + +void compute_att_control(struct angular_accel *vel, struct actuator_control *msg) { + msg->mode = 1; + msg->pitch = vel->accel; + msg->yaw = vel->accel * 10; +} + +void fw_att_control_update() { + struct angular_accel vel; + main_uorb.uorb_copy(&angular_velocity, fw_att_control_handle, &vel); + + struct actuator_control msg; + compute_att_control(&vel, &msg); + main_uorb.uorb_publish(&actuator_controls, &msg); +} + + +/* Camera */ +void cam_init() { + main_uorb.uorb_subscribe(&trigger); +} + +struct captured_image { + char buffer[100]; +}; + +void cam_capture() { + struct captured_image img; + main_uorb.uorb_publish(&camera_capture, &img); +} + +/* Airship Attitude Control */ +int airship_att_handle1; +int airship_att_handle2; +int airship_att_handle3; +void airship_att_start() { + airship_att_handle1 = main_uorb.uorb_subscribe(&vehicle_status); + airship_att_handle2 = main_uorb.uorb_subscribe(&angular_velocity); + airship_att_handle3 = main_uorb.uorb_subscribe(&manual_setpoint); +} + +void airship_att_stop() { + main_uorb.uorb_unsubscribe(&vehicle_status); + main_uorb.uorb_unsubscribe(&angular_velocity); + main_uorb.uorb_unsubscribe(&manual_setpoint); +} + +struct vehicle_status { + int on_fire; +}; + +struct setpoint { + int x; +}; +void airship_att_update() { + struct vehicle_status stat; + main_uorb.uorb_copy(&vehicle_status, airship_att_handle1, &stat); + struct angular_accel vel; + main_uorb.uorb_copy(&angular_velocity, airship_att_handle2, &vel); + struct setpoint sp; + main_uorb.uorb_copy(&manual_setpoint, airship_att_handle3, &sp); + + cam_capture(); + if(rand() < 5) { + airship_att_stop(); + } +} + +struct gyro_recalibrate { int tbd; }; +struct gyro_confirmed { bool confirmed; }; +struct gyro_alert_msg { bool out_of_range; }; + +void airship_att_recalibrate() { + struct gyro_status stat; + main_uorb.uorb_copy(&gyro, vehicle_angular_acc_handle, &stat); + if (stat.angleZ > 100) { + struct gyro_recalibrate rmsg; + struct gyro_confirmed cmsg = { .confirmed = false }; + for (int i = 0; i < 5 && !cmsg.confirmed; ++i) { + main_uorb.uorb_publish(&gyro, &rmsg); + main_uorb.uorb_copy(&gyro, vehicle_angular_acc_handle, &cmsg); + } + if (!cmsg.confirmed) { + struct gyro_alert_msg amsg = { .out_of_range = true }; + main_uorb.uorb_publish(&angular_velocity, &amsg); + } + } else { + struct angular_accel msg; + compute_angular_accel(&stat, &msg); + main_uorb.uorb_publish(&angular_velocity, &msg); + } +} + +/* Storage */ +void px4_log() { + main_uorb.uorb_subscribe(&vehicle_status); + main_uorb.uorb_subscribe(&battery_status); +} + +void subscribe_all() { + vehicle_angular_acc_start(); + vehicle_gps_start(); + fw_att_control_start(); + airship_att_start(); + gyro_start(); +} + +void run_control_cycle() { + vehicle_gps_update(); + vehicle_angular_acc_update(); + gyro_update(); + fw_att_control_update(); + airship_att_update(); + airship_att_recalibrate(); +} + +int main(int argc, char* argv[]) { + /* First, set up all of the subscriptions */ + subscribe_all(); + + while(1) { + run_control_cycle(); + } + + return 0; +} diff --git a/disasm-test/tests/p2.ll b/disasm-test/tests/p2.ll new file mode 100644 index 00000000..7805e4c9 --- /dev/null +++ b/disasm-test/tests/p2.ll @@ -0,0 +1,239 @@ +; ModuleID = 'p2.bc' +source_filename = "disasm-test/tests/p2.cpp" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%class.uorb = type { i8 } +%struct.gyro_status = type { double, double, double } +%struct.angular_accel = type { double } +%struct.actuator_control = type { i32, double, double } + +@main_uorb = local_unnamed_addr global %class.uorb zeroinitializer, align 1 +@vehicle_angular_acc_handle = local_unnamed_addr global i32 0, align 4 +@fw_att_control_handle = local_unnamed_addr global i32 0, align 4 +@airship_att_handle1 = local_unnamed_addr global i32 0, align 4 +@airship_att_handle2 = local_unnamed_addr global i32 0, align 4 +@airship_att_handle3 = local_unnamed_addr global i32 0, align 4 + +; Function Attrs: norecurse nounwind readnone sspstrong uwtable +define void @_Z17vehicle_gps_startv() local_unnamed_addr #0 { + ret void +} + +; Function Attrs: nounwind readnone sspstrong uwtable +define void @_Z18vehicle_gps_updatev() local_unnamed_addr #1 { + ret void +} + +; Function Attrs: norecurse nounwind readnone sspstrong uwtable +define void @_Z16vehicle_gps_stopv() local_unnamed_addr #0 { + ret void +} + +; Function Attrs: nofree norecurse nounwind sspstrong uwtable writeonly +define void @_Z25vehicle_angular_acc_startv() local_unnamed_addr #2 { + store i32 1, i32* @vehicle_angular_acc_handle, align 4, !tbaa !3 + ret void +} + +; Function Attrs: norecurse nounwind readnone sspstrong uwtable +define void @_Z24vehicle_angular_acc_stopv() local_unnamed_addr #0 { + ret void +} + +; Function Attrs: nofree norecurse nounwind sspstrong uwtable +define void @_Z21compute_angular_accelP11gyro_statusP13angular_accel(%struct.gyro_status* nocapture readonly %0, %struct.angular_accel* nocapture %1) local_unnamed_addr #3 { + %3 = getelementptr inbounds %struct.gyro_status, %struct.gyro_status* %0, i64 0, i32 0 + %4 = load double, double* %3, align 8, !tbaa !7 + %5 = fmul double %4, 1.000000e+02 + %6 = getelementptr inbounds %struct.gyro_status, %struct.gyro_status* %0, i64 0, i32 1 + %7 = load double, double* %6, align 8, !tbaa !10 + %8 = fadd double %5, %7 + %9 = getelementptr inbounds %struct.gyro_status, %struct.gyro_status* %0, i64 0, i32 2 + %10 = load double, double* %9, align 8, !tbaa !11 + %11 = fsub double %8, %10 + %12 = getelementptr inbounds %struct.angular_accel, %struct.angular_accel* %1, i64 0, i32 0 + store double %11, double* %12, align 8, !tbaa !12 + ret void +} + +; Function Attrs: nounwind readonly sspstrong uwtable +define void @_Z26vehicle_angular_acc_updatev() local_unnamed_addr #4 { + ret void +} + +; Function Attrs: norecurse nounwind readnone sspstrong uwtable +define void @_Z10gyro_startv() local_unnamed_addr #0 { + ret void +} + +; Function Attrs: nofree norecurse nounwind sspstrong uwtable +define void @_Z9read_gyroP11gyro_status(%struct.gyro_status* nocapture %0) local_unnamed_addr #3 { + %2 = load volatile double, double* inttoptr (i64 5592400 to double*), align 16, !tbaa !14 + %3 = getelementptr inbounds %struct.gyro_status, %struct.gyro_status* %0, i64 0, i32 0 + store double %2, double* %3, align 8, !tbaa !7 + %4 = load volatile double, double* inttoptr (i64 5592416 to double*), align 32, !tbaa !14 + %5 = getelementptr inbounds %struct.gyro_status, %struct.gyro_status* %0, i64 0, i32 1 + store double %4, double* %5, align 8, !tbaa !10 + %6 = load volatile double, double* inttoptr (i64 5592432 to double*), align 16, !tbaa !14 + %7 = getelementptr inbounds %struct.gyro_status, %struct.gyro_status* %0, i64 0, i32 2 + store double %6, double* %7, align 8, !tbaa !11 + ret void +} + +; Function Attrs: nounwind sspstrong uwtable +define i32 @_Z23gyro_calc_inconsistencyP11gyro_status(%struct.gyro_status* nocapture readnone %0) local_unnamed_addr #5 { + %2 = tail call i32 @rand() #8 + %3 = icmp slt i32 %2, 100 + %4 = zext i1 %3 to i32 + ret i32 %4 +} + +; Function Attrs: nounwind +declare i32 @rand() local_unnamed_addr #6 + +; Function Attrs: nounwind sspstrong uwtable +define void @_Z11gyro_updatev() local_unnamed_addr #5 { + %1 = load volatile double, double* inttoptr (i64 5592400 to double*), align 16, !tbaa !14 + %2 = load volatile double, double* inttoptr (i64 5592416 to double*), align 32, !tbaa !14 + %3 = load volatile double, double* inttoptr (i64 5592432 to double*), align 16, !tbaa !14 + %4 = tail call i32 @rand() #8 + ret void +} + +; Function Attrs: nofree norecurse nounwind sspstrong uwtable writeonly +define void @_Z20fw_att_control_startv() local_unnamed_addr #2 { + store i32 1, i32* @fw_att_control_handle, align 4, !tbaa !3 + ret void +} + +; Function Attrs: nofree norecurse nounwind sspstrong uwtable +define void @_Z19compute_att_controlP13angular_accelP16actuator_control(%struct.angular_accel* nocapture readonly %0, %struct.actuator_control* nocapture %1) local_unnamed_addr #3 { + %3 = getelementptr inbounds %struct.actuator_control, %struct.actuator_control* %1, i64 0, i32 0 + store i32 1, i32* %3, align 8, !tbaa !15 + %4 = bitcast %struct.angular_accel* %0 to i64* + %5 = load i64, i64* %4, align 8, !tbaa !12 + %6 = getelementptr inbounds %struct.actuator_control, %struct.actuator_control* %1, i64 0, i32 1 + %7 = bitcast double* %6 to i64* + store i64 %5, i64* %7, align 8, !tbaa !17 + %8 = bitcast i64 %5 to double + %9 = fmul double %8, 1.000000e+01 + %10 = getelementptr inbounds %struct.actuator_control, %struct.actuator_control* %1, i64 0, i32 2 + store double %9, double* %10, align 8, !tbaa !18 + ret void +} + +; Function Attrs: nounwind readonly sspstrong uwtable +define void @_Z21fw_att_control_updatev() local_unnamed_addr #4 { + ret void +} + +; Function Attrs: norecurse nounwind readnone sspstrong uwtable +define void @_Z8cam_initv() local_unnamed_addr #0 { + ret void +} + +; Function Attrs: nounwind readnone sspstrong uwtable +define void @_Z11cam_capturev() local_unnamed_addr #1 { + ret void +} + +; Function Attrs: nofree norecurse nounwind sspstrong uwtable writeonly +define void @_Z17airship_att_startv() local_unnamed_addr #2 { + store i32 1, i32* @airship_att_handle1, align 4, !tbaa !3 + store i32 1, i32* @airship_att_handle2, align 4, !tbaa !3 + store i32 1, i32* @airship_att_handle3, align 4, !tbaa !3 + ret void +} + +; Function Attrs: norecurse nounwind readnone sspstrong uwtable +define void @_Z16airship_att_stopv() local_unnamed_addr #0 { + ret void +} + +; Function Attrs: nounwind sspstrong uwtable +define void @_Z18airship_att_updatev() local_unnamed_addr #5 { + %1 = tail call i32 @rand() #8 + ret void +} + +; Function Attrs: nounwind readonly sspstrong uwtable +define void @_Z23airship_att_recalibratev() local_unnamed_addr #4 { + ret void +} + +; Function Attrs: norecurse nounwind readnone sspstrong uwtable +define void @_Z7px4_logv() local_unnamed_addr #0 { + ret void +} + +; Function Attrs: nofree norecurse nounwind sspstrong uwtable writeonly +define void @_Z13subscribe_allv() local_unnamed_addr #2 { + store i32 1, i32* @vehicle_angular_acc_handle, align 4, !tbaa !3 + store i32 1, i32* @fw_att_control_handle, align 4, !tbaa !3 + store i32 1, i32* @airship_att_handle1, align 4, !tbaa !3 + store i32 1, i32* @airship_att_handle2, align 4, !tbaa !3 + store i32 1, i32* @airship_att_handle3, align 4, !tbaa !3 + ret void +} + +; Function Attrs: nounwind sspstrong uwtable +define void @_Z17run_control_cyclev() local_unnamed_addr #5 { + %1 = load volatile double, double* inttoptr (i64 5592400 to double*), align 16, !tbaa !14 + %2 = load volatile double, double* inttoptr (i64 5592416 to double*), align 32, !tbaa !14 + %3 = load volatile double, double* inttoptr (i64 5592432 to double*), align 16, !tbaa !14 + %4 = tail call i32 @rand() #8 + %5 = tail call i32 @rand() #8 + ret void +} + +; Function Attrs: norecurse noreturn nounwind sspstrong uwtable +define i32 @main(i32 %0, i8** nocapture readnone %1) local_unnamed_addr #7 { + store i32 1, i32* @vehicle_angular_acc_handle, align 4, !tbaa !3 + store i32 1, i32* @fw_att_control_handle, align 4, !tbaa !3 + store i32 1, i32* @airship_att_handle1, align 4, !tbaa !3 + store i32 1, i32* @airship_att_handle2, align 4, !tbaa !3 + store i32 1, i32* @airship_att_handle3, align 4, !tbaa !3 + br label %3 + +3: ; preds = %2, %3 + %4 = load volatile double, double* inttoptr (i64 5592400 to double*), align 16, !tbaa !14 + %5 = load volatile double, double* inttoptr (i64 5592416 to double*), align 32, !tbaa !14 + %6 = load volatile double, double* inttoptr (i64 5592432 to double*), align 16, !tbaa !14 + %7 = tail call i32 @rand() #8 + %8 = tail call i32 @rand() #8 + br label %3 +} + +attributes #0 = { norecurse nounwind readnone sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nofree norecurse nounwind sspstrong uwtable writeonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { nofree norecurse nounwind sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #4 = { nounwind readonly sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #5 = { nounwind sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #6 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #7 = { norecurse noreturn nounwind sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #8 = { nounwind } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{!"clang version 11.1.0"} +!3 = !{!4, !4, i64 0} +!4 = !{!"int", !5, i64 0} +!5 = !{!"omnipotent char", !6, i64 0} +!6 = !{!"Simple C++ TBAA"} +!7 = !{!8, !9, i64 0} +!8 = !{!"_ZTS11gyro_status", !9, i64 0, !9, i64 8, !9, i64 16} +!9 = !{!"double", !5, i64 0} +!10 = !{!8, !9, i64 8} +!11 = !{!8, !9, i64 16} +!12 = !{!13, !9, i64 0} +!13 = !{!"_ZTS13angular_accel", !9, i64 0} +!14 = !{!9, !9, i64 0} +!15 = !{!16, !4, i64 0} +!16 = !{!"_ZTS16actuator_control", !4, i64 0, !9, i64 8, !9, i64 16} +!17 = !{!16, !9, i64 8} +!18 = !{!16, !9, i64 16}