diff --git a/expected_results.json b/expected_results.json index 5798d71b..09d4479f 100644 --- a/expected_results.json +++ b/expected_results.json @@ -1 +1 @@ -{"chapter_6/valid/rh_assignment.c": {"return_code": 1}, "chapter_6/valid/if_nested_2.c": {"return_code": 2}, "chapter_6/valid/if_nested_3.c": {"return_code": 3}, "chapter_6/valid/nested_ternary.c": {"return_code": 7}, "chapter_6/valid/binary_false_condition.c": {"return_code": 0}, "chapter_6/valid/else.c": {"return_code": 2}, "chapter_6/valid/nested_ternary_2.c": {"return_code": 15}, "chapter_6/valid/ternary_short_circuit.c": {"return_code": 1}, "chapter_6/valid/multiple_if.c": {"return_code": 8}, "chapter_6/valid/if_null_body.c": {"return_code": 1}, "chapter_6/valid/ternary_rh_binop.c": {"return_code": 1}, "chapter_6/valid/ternary_middle_assignment.c": {"return_code": 2}, "chapter_6/valid/if_nested_4.c": {"return_code": 4}, "chapter_6/valid/ternary_middle_binop.c": {"return_code": 1}, "chapter_6/valid/if_taken.c": {"return_code": 1}, "chapter_6/valid/if_not_taken.c": {"return_code": 0}, "chapter_6/valid/if_nested_5.c": {"return_code": 1}, "chapter_6/valid/assign_ternary.c": {"return_code": 2}, "chapter_6/valid/ternary.c": {"return_code": 4}, "chapter_6/valid/if_nested.c": {"return_code": 1}, "chapter_6/valid/ternary_short_circuit_2.c": {"return_code": 2}, "chapter_6/valid/binary_condition.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_and_var.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_main_2.c": {"return_code": 0}, "chapter_6/valid/extra_credit/bitwise_ternary.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_main.c": {"return_code": 0}, "chapter_6/valid/extra_credit/goto_nested_label.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_backwards.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label.c": {"return_code": 1}, "chapter_6/valid/extra_credit/compound_if_expression.c": {"return_code": 1}, "chapter_6/valid/extra_credit/goto_after_declaration.c": {"return_code": 1}, "chapter_8/valid/for.c": {"return_code": 16}, "chapter_8/valid/continue.c": {"return_code": 1}, "chapter_8/valid/multi_continue_same_loop.c": {"return_code": 1}, "chapter_8/valid/for_absent_post.c": {"return_code": 0}, "chapter_8/valid/null_for_header.c": {"return_code": 4}, "chapter_8/valid/nested_loop.c": {"return_code": 1}, "chapter_8/valid/nested_break.c": {"return_code": 250}, "chapter_8/valid/do_while.c": {"return_code": 16}, "chapter_8/valid/for_absent_condition.c": {"return_code": 0}, "chapter_8/valid/do_while_break_immediate.c": {"return_code": 10}, "chapter_8/valid/continue_empty_post.c": {"return_code": 30}, "chapter_8/valid/nested_continue.c": {"return_code": 24}, "chapter_8/valid/break.c": {"return_code": 1}, "chapter_8/valid/for_nested_shadow.c": {"return_code": 1}, "chapter_8/valid/empty_expression.c": {"return_code": 0}, "chapter_8/valid/multi_break.c": {"return_code": 1}, "chapter_8/valid/for_decl.c": {"return_code": 101}, "chapter_8/valid/for_shadow.c": {"return_code": 1}, "chapter_8/valid/break_immediate.c": {"return_code": 1}, "chapter_8/valid/while.c": {"return_code": 6}, "chapter_8/valid/empty_loop_body.c": {"return_code": 252}, "chapter_8/valid/extra_credit/switch_fallthrough.c": {"return_code": 4}, "chapter_8/valid/extra_credit/compound_assignment_for_loop.c": {"return_code": 10}, "chapter_8/valid/extra_credit/switch_break.c": {"return_code": 5}, "chapter_8/valid/extra_credit/switch_default.c": {"return_code": 22}, "chapter_8/valid/extra_credit/switch_default_fallthrough.c": {"return_code": 0}, "chapter_8/valid/extra_credit/switch_with_loop.c": {"return_code": 123}, "chapter_8/valid/extra_credit/switch_assign_in_body.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_in_loop.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_no_case.c": {"return_code": 4}, "chapter_8/valid/extra_credit/switch_nested_case.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_nested_not_taken.c": {"return_code": 2}, "chapter_8/valid/extra_credit/switch_decl.c": {"return_code": 7}, "chapter_8/valid/extra_credit/switch_with_continue.c": {"return_code": 5}, "chapter_8/valid/extra_credit/switch_empty.c": {"return_code": 10}, "chapter_8/valid/extra_credit/goto_loop_body.c": {"return_code": 1}, "chapter_8/valid/extra_credit/goto_bypass_condition.c": {"return_code": 10}, "chapter_8/valid/extra_credit/switch_nested_switch.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_block.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_default_not_last.c": {"return_code": 0}, "chapter_8/valid/extra_credit/switch_assign_in_condition.c": {"return_code": 2}, "chapter_8/valid/extra_credit/switch.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_goto_mid_case.c": {"return_code": 1}, "chapter_14/valid/libraries/static_pointer.c": {"return_code": 0}, "chapter_14/valid/libraries/global_pointer.c": {"return_code": 1}, "chapter_14/valid/function_calls/address_of_argument.c": {"return_code": 0}, "chapter_14/valid/function_calls/update_value_through_pointer_parameter.c": {"return_code": 0}, "chapter_14/valid/function_calls/return_pointer.c": {"return_code": 0}, "chapter_14/valid/extra_credit/incr_through_pointer.c": {"return_code": 11}, "chapter_14/valid/extra_credit/compound_assign_through_pointer.c": {"return_code": 1}, "chapter_14/valid/declarators/declare_pointer_in_for_loop.c": {"return_code": 5}, "chapter_14/valid/declarators/abstract_declarators.c": {"return_code": 0}, "chapter_14/valid/declarators/declarators.c": {"return_code": 0}, "chapter_14/valid/dereference/static_var_indirection.c": {"return_code": 0}, "chapter_14/valid/dereference/multilevel_indirection.c": {"return_code": 0}, "chapter_14/valid/dereference/read_through_pointers.c": {"return_code": 0}, "chapter_14/valid/dereference/update_through_pointers.c": {"return_code": 0}, "chapter_14/valid/dereference/address_of_dereference.c": {"return_code": 0}, "chapter_14/valid/dereference/simple.c": {"return_code": 3}, "chapter_14/valid/dereference/dereference_expression_result.c": {"return_code": 0}, "chapter_14/valid/casts/cast_between_pointer_types.c": {"return_code": 0}, "chapter_14/valid/casts/pointer_int_casts.c": {"return_code": 0}, "chapter_14/valid/casts/null_pointer_conversion.c": {"return_code": 0}, "chapter_14/valid/comparisons/compare_pointers.c": {"return_code": 0}, "chapter_14/valid/comparisons/pointers_as_conditions.c": {"return_code": 0}, "chapter_14/valid/comparisons/compare_to_null.c": {"return_code": 0}, "chapter_10/valid/static_then_extern.c": {"return_code": 3}, "chapter_10/valid/push_arg_on_page_boundary.c": {"return_code": 1}, "chapter_10/valid/static_local_multiple_scopes.c": {"return_code": 0, "stdout": "Aa\nBb\nCc\nDd\nEe\nFf\nGg\nHh\nIi\nJj\nKk\nLl\nMm\nNn\nOo\nPp\nQq\nRr\nSs\nTt\nUu\nVv\nWw\nXx\nYy\nZz\n"}, "chapter_10/valid/tentative_definition.c": {"return_code": 5}, "chapter_10/valid/static_variables_in_expressions.c": {"return_code": 0}, "chapter_10/valid/static_recursive_call.c": {"return_code": 0, "stdout": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, "chapter_10/valid/shadow_static_local_var.c": {"return_code": 0}, "chapter_10/valid/multiple_static_local.c": {"return_code": 29}, "chapter_10/valid/multiple_static_file_scope_vars.c": {"return_code": 4}, "chapter_10/valid/static_local_uninitialized.c": {"return_code": 4}, "chapter_10/valid/type_before_storage_class.c": {"return_code": 7}, "chapter_10/valid/extern_block_scope_variable.c": {"return_code": 3}, "chapter_10/valid/distinct_local_and_extern.c": {"return_code": 7}, "chapter_10/valid/libraries/internal_hides_external_linkage.c": {"return_code": 0}, "chapter_10/valid/libraries/external_tentative_var.c": {"return_code": 0}, "chapter_10/valid/libraries/external_linkage_function.c": {"return_code": 0}, "chapter_10/valid/libraries/external_variable.c": {"return_code": 0}, "chapter_10/valid/libraries/internal_linkage_var.c": {"return_code": 0}, "chapter_10/valid/libraries/external_var_scoping.c": {"return_code": 0}, "chapter_10/valid/libraries/internal_linkage_function.c": {"return_code": 0}, "chapter_10/valid/extra_credit/goto_skip_static_initializer.c": {"return_code": 10}, "chapter_2/valid/neg.c": {"return_code": 251}, "chapter_2/valid/negate_int_max.c": {"return_code": 1}, "chapter_2/valid/redundant_parens.c": {"return_code": 246}, "chapter_2/valid/neg_zero.c": {"return_code": 0}, "chapter_2/valid/bitwise_int_min.c": {"return_code": 254}, "chapter_2/valid/bitwise_zero.c": {"return_code": 255}, "chapter_2/valid/parens_3.c": {"return_code": 4}, "chapter_2/valid/parens_2.c": {"return_code": 253}, "chapter_2/valid/bitwise.c": {"return_code": 243}, "chapter_2/valid/nested_ops_2.c": {"return_code": 1}, "chapter_2/valid/nested_ops.c": {"return_code": 2}, "chapter_2/valid/parens.c": {"return_code": 254}, "chapter_1/valid/return_0.c": {"return_code": 0}, "chapter_1/valid/newlines.c": {"return_code": 0}, "chapter_1/valid/return_2.c": {"return_code": 2}, "chapter_1/valid/multi_digit.c": {"return_code": 100}, "chapter_1/valid/tabs.c": {"return_code": 0}, "chapter_1/valid/spaces.c": {"return_code": 0}, "chapter_1/valid/no_newlines.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/logical.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/static_initialized_double.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/comparisons.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/simple.c": {"return_code": 1}, "chapter_13/valid/floating_expressions/loop_controlling_expression.c": {"return_code": 100}, "chapter_13/valid/libraries/double_parameters.c": {"return_code": 0}, "chapter_13/valid/libraries/use_arg_after_fun_call.c": {"return_code": 4}, "chapter_13/valid/libraries/double_and_int_params_recursive.c": {"return_code": 0}, "chapter_13/valid/libraries/extern_double.c": {"return_code": 1}, "chapter_13/valid/libraries/double_params_and_result.c": {"return_code": 1}, "chapter_13/valid/explicit_casts/cvttsd2i_rewrite.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/double_to_signed.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/unsigned_to_double.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/signed_to_double.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/double_to_unsigned.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/convert_for_assignment.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/static_initializers.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/complex_arithmetic_common_type.c": {"return_code": 1}, "chapter_13/valid/constants/round_constants.c": {"return_code": 0}, "chapter_13/valid/constants/constant_doubles.c": {"return_code": 0}, "chapter_13/valid/special_values/subnormal_not_zero.c": {"return_code": 0}, "chapter_13/valid/special_values/negative_zero.c": {"return_code": 0}, "chapter_13/valid/special_values/infinity.c": {"return_code": 0}, "chapter_13/valid/function_calls/double_parameters.c": {"return_code": 0}, "chapter_13/valid/function_calls/double_and_int_parameters.c": {"return_code": 0}, "chapter_13/valid/function_calls/standard_library_call.c": {"return_code": 0}, "chapter_13/valid/function_calls/use_arg_after_fun_call.c": {"return_code": 4}, "chapter_13/valid/function_calls/return_double.c": {"return_code": 1}, "chapter_13/valid/function_calls/double_and_int_params_recursive.c": {"return_code": 0}, "chapter_13/valid/extra_credit/compound_assign.c": {"return_code": 1}, "chapter_13/valid/extra_credit/nan.c": {"return_code": 0}, "chapter_13/valid/extra_credit/compound_assign_implicit_cast.c": {"return_code": 1}, "chapter_18/valid/params_and_returns/temporary_lifetime.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/ignore_retval.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_space_overlap.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_big_struct_on_page_boundary.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/simple.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_struct_on_page_boundary.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_incomplete_type.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/stack_clobber.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/libraries/missing_retval.c": {"return_code": 1}, "chapter_18/valid/params_and_returns/libraries/access_retval_members.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/semantic_analysis/resolve_tags.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/semantic_analysis/namespaces.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/semantic_analysis/incomplete_structs.c": {"return_code": 0, "stdout": "I'm a struct!\n"}, "chapter_18/valid/no_structure_parameters/semantic_analysis/cast_struct_to_void.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/global_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/param_struct_pointer.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/return_struct_pointer.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/opaque_struct.c": {"return_code": 0, "stdout": "new struct\nstatic struct\nglobal struct\n"}, "chapter_18/valid/no_structure_parameters/libraries/array_of_structs.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/auto_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/static_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/nested_static_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/nested_auto_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/smoke_tests/static_vs_auto.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/smoke_tests/simple.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/member_offsets.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/sizeof_exps.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/sizeof_type.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/arrow.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/linked_list.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/static_structs.c": {"return_code": 0, "stdout": "zero\nmn\nop\nwx\nyz\nBCD\nCDE\nDEF\nEFG\nbcd\ncde\n"}, "chapter_18/valid/no_structure_parameters/scalar_member_access/nested_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/dot.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/parse_and_lex/postfix_precedence.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/parse_and_lex/trailing_comma.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/parse_and_lex/space_around_struct_member.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/parse_and_lex/struct_member_looks_like_const.c": {"return_code": 3}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_with_arrow_operator.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/stack_clobber.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_with_dot_operator.c": {"return_code": 0}, "chapter_18/valid/parameters/pass_args_on_page_boundary.c": {"return_code": 0}, "chapter_18/valid/parameters/incomplete_param_type.c": {"return_code": 3}, "chapter_18/valid/parameters/simple.c": {"return_code": 0}, "chapter_18/valid/parameters/stack_clobber.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/param_calling_conventions.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/struct_sizes.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/pass_struct.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/modify_param.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/classify_params.c": {"return_code": 0}, "chapter_15/valid/initialization/automatic.c": {"return_code": 0}, "chapter_15/valid/initialization/static.c": {"return_code": 0}, "chapter_15/valid/initialization/trailing_comma_initializer.c": {"return_code": 3}, "chapter_15/valid/initialization/automatic_nested.c": {"return_code": 0}, "chapter_15/valid/initialization/static_nested.c": {"return_code": 0}, "chapter_15/valid/libraries/set_array_val.c": {"return_code": 0}, "chapter_15/valid/libraries/return_pointer_to_array.c": {"return_code": 0}, "chapter_15/valid/libraries/global_array.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_nested.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_pointer.c": {"return_code": 0}, "chapter_15/valid/subscripting/array_of_pointers_to_arrays.c": {"return_code": 0}, "chapter_15/valid/subscripting/simple_subscripts.c": {"return_code": 0}, "chapter_15/valid/subscripting/simple.c": {"return_code": 3}, "chapter_15/valid/subscripting/complex_operands.c": {"return_code": 0}, "chapter_15/valid/subscripting/addition_subscript_equivalence.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_precedence.c": {"return_code": 1}, "chapter_15/valid/allocation/test_alignment.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/pointer_add.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/add_dereference_and_assign.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/pointer_diff.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/compare.c": {"return_code": 0}, "chapter_15/valid/extra_credit/incr_ptr.c": {"return_code": 1}, "chapter_15/valid/declarators/big_array.c": {"return_code": 0}, "chapter_15/valid/declarators/equivalent_declarators.c": {"return_code": 0}, "chapter_15/valid/declarators/return_nested_array.c": {"return_code": 0}, "chapter_15/valid/declarators/array_as_argument.c": {"return_code": 0}, "chapter_15/valid/declarators/for_loop_array.c": {"return_code": 0}, "chapter_15/valid/casts/multi_dim_casts.c": {"return_code": 0}, "chapter_15/valid/casts/implicit_and_explicit_conversions.c": {"return_code": 0}, "chapter_15/valid/casts/cast_array_of_pointers.c": {"return_code": 1}, "chapter_17/valid/void/cast_to_void.c": {"return_code": 12}, "chapter_17/valid/void/void_function.c": {"return_code": 0}, "chapter_17/valid/void/void_for_loop.c": {"return_code": 0, "stdout": "ZYXWVUTSRQPONMLKJIHGFEDCBAABCDEFGHIJKLMNOPQRSTUVWXYZZYXWVUTSRQPONMLKJIHGFEDCBA"}, "chapter_17/valid/void/ternary.c": {"return_code": 0}, "chapter_17/valid/libraries/pass_alloced_memory.c": {"return_code": 0}, "chapter_17/valid/libraries/test_for_memory_leaks.c": {"return_code": 0}, "chapter_17/valid/libraries/sizeof_extern.c": {"return_code": 1}, "chapter_17/valid/sizeof/sizeof_basic_types.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_consts.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_expressions.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_array.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_derived_types.c": {"return_code": 0}, "chapter_17/valid/sizeof/simple.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_result_is_ulong.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_not_evaluated.c": {"return_code": 4}, "chapter_17/valid/void_pointer/array_of_pointers_to_void.c": {"return_code": 0}, "chapter_17/valid/void_pointer/conversion_by_assignment.c": {"return_code": 0}, "chapter_17/valid/void_pointer/explicit_cast.c": {"return_code": 0}, "chapter_17/valid/void_pointer/simple.c": {"return_code": 100}, "chapter_17/valid/void_pointer/memory_management_functions.c": {"return_code": 0}, "chapter_17/valid/void_pointer/common_pointer_type.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/addr_of_string.c": {"return_code": 0, "stdout": "Sample\tstring!\n\n"}, "chapter_16/valid/strings_as_lvalues/standard_library_calls.c": {"return_code": 0, "stdout": "Hello, World!\n"}, "chapter_16/valid/strings_as_lvalues/array_of_strings.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/cast_string_pointer.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/empty_string.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/pointer_operations.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/simple.c": {"return_code": 108}, "chapter_16/valid/strings_as_lvalues/adjacent_strings.c": {"return_code": 0, "stdout": "Hello, World\n"}, "chapter_16/valid/strings_as_lvalues/string_special_characters.c": {"return_code": 0, "stdout": "Hello\"world\nHello\\World\nLine\nbreak!\nTesting, 123.\n^@1 _\\]\n"}, "chapter_16/valid/strings_as_lvalues/strings_in_function_calls.c": {"return_code": 0}, "chapter_16/valid/libraries/return_char.c": {"return_code": 0}, "chapter_16/valid/libraries/char_arguments.c": {"return_code": 0}, "chapter_16/valid/libraries/global_char.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/array_init_special_chars.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/terminating_null_bytes.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/simple.c": {"return_code": 99}, "chapter_16/valid/strings_as_initializers/partial_initialize_via_string.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/adjacent_strings_in_initializer.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/transfer_by_eightbyte.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/literals_and_compound_initializers.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/write_to_array.c": {"return_code": 0, "stdout": "abc\nabx\nHello\nWorld\nJello\n"}, "chapter_16/valid/strings_as_initializers/test_alignment.c": {"return_code": 0}, "chapter_16/valid/char_constants/return_char_constant.c": {"return_code": 99}, "chapter_16/valid/char_constants/escape_sequences.c": {"return_code": 0}, "chapter_16/valid/char_constants/control_characters.c": {"return_code": 0}, "chapter_16/valid/char_constants/char_constant_operations.c": {"return_code": 0}, "chapter_16/valid/chars/partial_initialization.c": {"return_code": 0}, "chapter_16/valid/chars/convert_by_assignment.c": {"return_code": 0}, "chapter_16/valid/chars/type_specifiers.c": {"return_code": 0}, "chapter_16/valid/chars/push_arg_on_page_boundary.c": {"return_code": 1}, "chapter_16/valid/chars/integer_promotion.c": {"return_code": 0}, "chapter_16/valid/chars/chained_casts.c": {"return_code": 0}, "chapter_16/valid/chars/return_char.c": {"return_code": 0}, "chapter_16/valid/chars/char_arguments.c": {"return_code": 0}, "chapter_16/valid/chars/char_expressions.c": {"return_code": 0}, "chapter_16/valid/chars/access_through_char_pointer.c": {"return_code": 0}, "chapter_16/valid/chars/common_type.c": {"return_code": 0}, "chapter_16/valid/chars/static_initializers.c": {"return_code": 0}, "chapter_16/valid/chars/explicit_casts.c": {"return_code": 0}, "chapter_9/valid/arguments_in_registers/parameter_shadows_own_function.c": {"return_code": 2}, "chapter_9/valid/arguments_in_registers/expression_args.c": {"return_code": 2}, "chapter_9/valid/arguments_in_registers/single_arg.c": {"return_code": 6}, "chapter_9/valid/arguments_in_registers/hello_world.c": {"return_code": 0, "stdout": "Hello, World!\n"}, "chapter_9/valid/arguments_in_registers/parameter_shadows_function.c": {"return_code": 3}, "chapter_9/valid/arguments_in_registers/parameters_are_preserved.c": {"return_code": 1}, "chapter_9/valid/arguments_in_registers/forward_decl_multi_arg.c": {"return_code": 1}, "chapter_9/valid/arguments_in_registers/fibonacci.c": {"return_code": 8}, "chapter_9/valid/arguments_in_registers/param_shadows_local_var.c": {"return_code": 20}, "chapter_9/valid/no_arguments/function_shadows_variable.c": {"return_code": 11}, "chapter_9/valid/no_arguments/use_function_in_expression.c": {"return_code": 21}, "chapter_9/valid/no_arguments/no_return_value.c": {"return_code": 3}, "chapter_9/valid/no_arguments/multiple_declarations.c": {"return_code": 3}, "chapter_9/valid/no_arguments/precedence.c": {"return_code": 0}, "chapter_9/valid/no_arguments/forward_decl.c": {"return_code": 3}, "chapter_9/valid/no_arguments/variable_shadows_function.c": {"return_code": 7}, "chapter_9/valid/libraries/system_call.c": {"return_code": 0, "stdout": "H"}, "chapter_9/valid/libraries/many_args.c": {"return_code": 115}, "chapter_9/valid/libraries/addition.c": {"return_code": 3}, "chapter_9/valid/libraries/no_function_calls/division.c": {"return_code": 1}, "chapter_9/valid/libraries/no_function_calls/local_stack_variables.c": {"return_code": 100}, "chapter_9/valid/extra_credit/compound_assign_function_result.c": {"return_code": 1}, "chapter_9/valid/extra_credit/goto_label_multiple_functions.c": {"return_code": 5}, "chapter_9/valid/extra_credit/goto_shared_name.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/call_putchar.c": {"return_code": 8, "stdout": "A"}, "chapter_9/valid/stack_arguments/lots_of_arguments.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/stack_alignment.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/test_for_memory_leaks.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/logical.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/arithmetic_wraparound.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/comparisons.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/simple.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/static_variables.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/locals.c": {"return_code": 0}, "chapter_12/valid/libraries/unsigned_args.c": {"return_code": 0}, "chapter_12/valid/libraries/unsigned_global_var.c": {"return_code": 1}, "chapter_12/valid/explicit_casts/same_size_conversion.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/extension.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/round_trip_casts.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/chained_casts.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/truncate.c": {"return_code": 0}, "chapter_12/valid/type_specifiers/signed_type_specifiers.c": {"return_code": 0}, "chapter_12/valid/type_specifiers/unsigned_type_specifiers.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/convert_by_assignment.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/promote_constants.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/static_initializers.c": {"return_code": 0}, "chapter_12/valid/extra_credit/switch_uint.c": {"return_code": 0}, "chapter_12/valid/extra_credit/compound_assign_uint.c": {"return_code": 1}, "chapter_12/valid/extra_credit/bitwise_unsigned_shift.c": {"return_code": 1}, "chapter_12/valid/extra_credit/bitwise_unsigned_ops.c": {"return_code": 1}, "chapter_5/valid/null_then_return.c": {"return_code": 0}, "chapter_5/valid/empty_function_body.c": {"return_code": 0}, "chapter_5/valid/short_circuit_or.c": {"return_code": 0}, "chapter_5/valid/assignment_in_initializer.c": {"return_code": 0}, "chapter_5/valid/non_short_circuit_or.c": {"return_code": 1}, "chapter_5/valid/null_statement.c": {"return_code": 0}, "chapter_5/valid/short_circuit_and_fail.c": {"return_code": 0}, "chapter_5/valid/local_var_missing_return.c": {"return_code": 0}, "chapter_5/valid/exp_then_declaration.c": {"return_code": 1}, "chapter_5/valid/add_variables.c": {"return_code": 3}, "chapter_5/valid/assign_val_in_initializer.c": {"return_code": 5}, "chapter_5/valid/assignment_lowest_precedence.c": {"return_code": 1}, "chapter_5/valid/allocate_temps_and_vars.c": {"return_code": 1}, "chapter_5/valid/use_assignment_result.c": {"return_code": 4}, "chapter_5/valid/use_val_in_own_initializer.c": {"return_code": 0}, "chapter_5/valid/unused_exp.c": {"return_code": 0}, "chapter_5/valid/return_var.c": {"return_code": 2}, "chapter_5/valid/mixed_precedence_assignment.c": {"return_code": 4}, "chapter_5/valid/assign.c": {"return_code": 2}, "chapter_5/valid/extra_credit/bitwise_shiftr_assign.c": {"return_code": 77}, "chapter_5/valid/extra_credit/bitwise_shiftl_variable.c": {"return_code": 24}, "chapter_5/valid/extra_credit/compound_bitwise_and.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_minus.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_multiply.c": {"return_code": 12}, "chapter_5/valid/extra_credit/compound_bitwise_xor.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_bitwise_or.c": {"return_code": 31}, "chapter_5/valid/extra_credit/compound_assignment_chained.c": {"return_code": 4}, "chapter_5/valid/extra_credit/compound_divide.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_bitwise_shiftr.c": {"return_code": 102}, "chapter_5/valid/extra_credit/compound_assignment_use_result.c": {"return_code": 8}, "chapter_5/valid/extra_credit/compound_bitwise_shiftl.c": {"return_code": 48}, "chapter_5/valid/extra_credit/compound_plus.c": {"return_code": 4}, "chapter_5/valid/extra_credit/compound_mod.c": {"return_code": 2}, "chapter_5/valid/extra_credit/bitwise_and_vars.c": {"return_code": 1}, "chapter_7/valid/declaration_only.c": {"return_code": 1}, "chapter_7/valid/assign_to_self_2.c": {"return_code": 3}, "chapter_7/valid/hidden_then_visible.c": {"return_code": 1}, "chapter_7/valid/hidden_variable.c": {"return_code": 1}, "chapter_7/valid/assign_to_self.c": {"return_code": 4}, "chapter_7/valid/inner_uninitialized.c": {"return_code": 4}, "chapter_7/valid/multiple_vars_same_name.c": {"return_code": 2}, "chapter_7/valid/use_in_inner_scope.c": {"return_code": 3}, "chapter_7/valid/empty_blocks.c": {"return_code": 30}, "chapter_7/valid/nested_if.c": {"return_code": 1}, "chapter_7/valid/similar_var_names.c": {"return_code": 28}, "chapter_7/valid/extra_credit/goto_before_declaration.c": {"return_code": 0}, "chapter_7/valid/extra_credit/compound_subtract_in_block.c": {"return_code": 1}, "chapter_7/valid/extra_credit/goto_inner_scope.c": {"return_code": 1}, "chapter_4/valid/le_true.c": {"return_code": 2}, "chapter_4/valid/ne_true.c": {"return_code": 1}, "chapter_4/valid/ge_false.c": {"return_code": 0}, "chapter_4/valid/not_zero.c": {"return_code": 1}, "chapter_4/valid/precedence_2.c": {"return_code": 0}, "chapter_4/valid/ge_true.c": {"return_code": 2}, "chapter_4/valid/eq_precedence.c": {"return_code": 1}, "chapter_4/valid/eq_false.c": {"return_code": 0}, "chapter_4/valid/or_short_circuit.c": {"return_code": 1}, "chapter_4/valid/not_sum.c": {"return_code": 1}, "chapter_4/valid/precedence_4.c": {"return_code": 1}, "chapter_4/valid/and_short_circuit.c": {"return_code": 0}, "chapter_4/valid/precedence_3.c": {"return_code": 0}, "chapter_4/valid/compare_arithmetic_results.c": {"return_code": 1}, "chapter_4/valid/and_false.c": {"return_code": 0}, "chapter_4/valid/precedence_5.c": {"return_code": 1}, "chapter_4/valid/associativity.c": {"return_code": 1}, "chapter_4/valid/gt_true.c": {"return_code": 1}, "chapter_4/valid/lt_false.c": {"return_code": 0}, "chapter_4/valid/or_true.c": {"return_code": 3}, "chapter_4/valid/or_false.c": {"return_code": 0}, "chapter_4/valid/eq_true.c": {"return_code": 1}, "chapter_4/valid/ne_false.c": {"return_code": 0}, "chapter_4/valid/multi_short_circuit.c": {"return_code": 0}, "chapter_4/valid/gt_false.c": {"return_code": 0}, "chapter_4/valid/operate_on_booleans.c": {"return_code": 0}, "chapter_4/valid/not.c": {"return_code": 0}, "chapter_4/valid/le_false.c": {"return_code": 0}, "chapter_4/valid/nested_ops.c": {"return_code": 0}, "chapter_4/valid/precedence.c": {"return_code": 1}, "chapter_4/valid/not_sum_2.c": {"return_code": 0}, "chapter_4/valid/and_true.c": {"return_code": 1}, "chapter_4/valid/lt_true.c": {"return_code": 1}, "chapter_4/valid/extra_credit/bitwise_precedence.c": {"return_code": 1}, "chapter_3/valid/mod.c": {"return_code": 0}, "chapter_3/valid/unop_add.c": {"return_code": 0}, "chapter_3/valid/associativity_3.c": {"return_code": 8}, "chapter_3/valid/mult.c": {"return_code": 6}, "chapter_3/valid/sub.c": {"return_code": 255}, "chapter_3/valid/div_neg.c": {"return_code": 254}, "chapter_3/valid/unop_parens.c": {"return_code": 253}, "chapter_3/valid/add.c": {"return_code": 3}, "chapter_3/valid/associativity.c": {"return_code": 252}, "chapter_3/valid/associativity_2.c": {"return_code": 1}, "chapter_3/valid/div.c": {"return_code": 2}, "chapter_3/valid/sub_neg.c": {"return_code": 3}, "chapter_3/valid/associativity_and_precedence.c": {"return_code": 10}, "chapter_3/valid/parens.c": {"return_code": 14}, "chapter_3/valid/precedence.c": {"return_code": 14}, "chapter_3/valid/extra_credit/bitwise_shiftr.c": {"return_code": 62}, "chapter_3/valid/extra_credit/bitwise_and.c": {"return_code": 1}, "chapter_3/valid/extra_credit/bitwise_shiftl.c": {"return_code": 140}, "chapter_3/valid/extra_credit/bitwise_or.c": {"return_code": 3}, "chapter_3/valid/extra_credit/bitwise_shift_precedence.c": {"return_code": 0}, "chapter_3/valid/extra_credit/bitwise_xor.c": {"return_code": 6}, "chapter_3/valid/extra_credit/bitwise_shift_associativity_2.c": {"return_code": 16}, "chapter_3/valid/extra_credit/bitwise_shift_associativity.c": {"return_code": 66}, "chapter_3/valid/extra_credit/bitwise_precedence.c": {"return_code": 21}, "chapter_11/valid/long_expressions/long_args.c": {"return_code": 0}, "chapter_11/valid/long_expressions/logical.c": {"return_code": 0}, "chapter_11/valid/long_expressions/type_specifiers.c": {"return_code": 0}, "chapter_11/valid/long_expressions/multi_op.c": {"return_code": 1}, "chapter_11/valid/long_expressions/large_constants.c": {"return_code": 0}, "chapter_11/valid/long_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_11/valid/long_expressions/return_long.c": {"return_code": 1}, "chapter_11/valid/long_expressions/comparisons.c": {"return_code": 0}, "chapter_11/valid/long_expressions/simple.c": {"return_code": 1}, "chapter_11/valid/long_expressions/static_long.c": {"return_code": 1}, "chapter_11/valid/long_expressions/long_and_int_locals.c": {"return_code": 0}, "chapter_11/valid/long_expressions/assign.c": {"return_code": 1}, "chapter_11/valid/libraries/long_args.c": {"return_code": 0}, "chapter_11/valid/libraries/maintain_stack_alignment.c": {"return_code": 12}, "chapter_11/valid/libraries/return_long.c": {"return_code": 1}, "chapter_11/valid/libraries/long_global_var.c": {"return_code": 0}, "chapter_11/valid/explicit_casts/truncate.c": {"return_code": 0}, "chapter_11/valid/explicit_casts/sign_extend.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_by_assignment.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/long_constants.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_function_arguments.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_static_initializer.c": {"return_code": 0}, "chapter_11/valid/extra_credit/bitwise_long_op.c": {"return_code": 1}, "chapter_11/valid/extra_credit/compound_assign_to_int.c": {"return_code": 1}, "chapter_11/valid/extra_credit/compound_assign_to_long.c": {"return_code": 1}, "chapter_11/valid/extra_credit/switch_int.c": {"return_code": 1}, "chapter_11/valid/extra_credit/switch_long.c": {"return_code": 1}, "chapter_19/constant_folding/all_types/fold_truncate.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_cast_to_double.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_ulong.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_double.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_extensions_and_copies.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_long.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_uint.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_cast_from_double.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_unary.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_conditional_jump.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_binary.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_control_flow.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_exception.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/remove_useless_starting_label.c": {"return_code": 99}, "chapter_19/unreachable_code_elimination/dead_for_loop.c": {"return_code": 10}, "chapter_19/unreachable_code_elimination/keep_final_jump.c": {"return_code": 17}, "chapter_19/unreachable_code_elimination/remove_jump_keep_label.c": {"return_code": 10}, "chapter_19/unreachable_code_elimination/dead_branch_inside_loop.c": {"return_code": 19}, "chapter_19/unreachable_code_elimination/empty.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/infinite_loop.c": {"return_code": 11}, "chapter_19/unreachable_code_elimination/constant_if_else.c": {"return_code": 45}, "chapter_19/unreachable_code_elimination/dead_blocks_with_predecessors.c": {"return_code": 5}, "chapter_19/unreachable_code_elimination/remove_conditional_jumps.c": {"return_code": 1}, "chapter_19/unreachable_code_elimination/dead_after_return.c": {"return_code": 2}, "chapter_19/unreachable_code_elimination/empty_block.c": {"return_code": 1}, "chapter_19/unreachable_code_elimination/dead_after_if_else.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/pointer_arithmetic.c": {"return_code": 2}, "chapter_19/copy_propagation/all_types/store_doesnt_kill.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/propagate_into_type_conversions.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/redundant_double_copies.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/char_type_conversion.c": {"return_code": 1, "stdout": "CBA@"}, "chapter_19/copy_propagation/all_types/alias_analysis.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/copy_struct.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/redundant_struct_copies.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/propagate_null_pointer.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/propagate_all_types.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/funcall_kills_aliased.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/static_are_aliased.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/store_kills_aliased.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/copy_to_offset.c": {"return_code": 3}, "chapter_19/copy_propagation/all_types/dont_propagate/dont_propagate_addr_of.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/type_conversion.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/dont_propagate/zero_neg_zero_different.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/killed_then_redefined.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/different_paths_same_copy.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/multi_path_no_kill.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/redundant_copies.c": {"return_code": 20}, "chapter_19/copy_propagation/int_only/fig_19_8.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/propagate_into_complex_expressions.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/propagate_static.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/propagate_static_var.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/kill_and_add_copies.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/init_all_copies.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/propagate_params.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/nested_loops.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/constant_propagation.c": {"return_code": 6}, "chapter_19/copy_propagation/int_only/propagate_var.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/different_source_values_same_copy.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/dont_propagate/source_killed_on_one_path.c": {"return_code": 0, "stdout": "DA"}, "chapter_19/copy_propagation/int_only/dont_propagate/one_reaching_copy.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/dont_propagate/dest_killed.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/no_copies_reach_entry.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/listing_19_14.c": {"return_code": 101}, "chapter_19/copy_propagation/int_only/dont_propagate/add_all_blocks_to_worklist.c": {"return_code": 100}, "chapter_19/copy_propagation/int_only/dont_propagate/multi_values.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/dont_propagate/static_dst_killed.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/dont_propagate/static_src_killed.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/dont_propagate/source_killed.c": {"return_code": 0}, "chapter_19/dead_store_elimination/all_types/aliased_dead_at_exit.c": {"return_code": 1}, "chapter_19/dead_store_elimination/all_types/getaddr_doesnt_gen.c": {"return_code": 0}, "chapter_19/dead_store_elimination/all_types/copy_to_dead_struct.c": {"return_code": 4}, "chapter_19/dead_store_elimination/all_types/dont_elim/copytooffset_doesnt_kill.c": {"return_code": 1}, "chapter_19/dead_store_elimination/all_types/dont_elim/never_kill_store.c": {"return_code": 4}, "chapter_19/dead_store_elimination/int_only/dead_store_static_var.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/loop_dead_store.c": {"return_code": 0, "stdout": "CHNTZ"}, "chapter_19/dead_store_elimination/int_only/simple.c": {"return_code": 3}, "chapter_19/dead_store_elimination/int_only/elim_second_copy.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/dont_elim/static_vars_at_exit.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/dont_elim/used_one_path.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/dont_elim/dont_remove_funcall.c": {"return_code": 0, "stdout": "C"}, "chapter_19/dead_store_elimination/int_only/dont_elim/add_all_to_worklist.c": {"return_code": 0, "stdout": "ML"}, "chapter_19/dead_store_elimination/int_only/dont_elim/loop.c": {"return_code": 1}, "chapter_19/dead_store_elimination/int_only/dont_elim/static_vars_fun.c": {"return_code": 5}, "chapter_19/whole_pipeline/all_types/unsigned_wraparound.c": {"return_code": 1}, "chapter_19/whole_pipeline/all_types/unsigned_compare.c": {"return_code": 1}, "chapter_19/whole_pipeline/all_types/signed_unsigned_conversion.c": {"return_code": 1}, "chapter_19/whole_pipeline/all_types/alias_analysis_change.c": {"return_code": 0}, "chapter_19/whole_pipeline/all_types/not_char.c": {"return_code": 1}, "chapter_19/whole_pipeline/all_types/const_fold_sign_extend.c": {"return_code": 1}, "chapter_19/whole_pipeline/all_types/char_round_trip.c": {"return_code": 1}, "chapter_19/whole_pipeline/all_types/const_fold_sign_extend_2.c": {"return_code": 1}, "chapter_19/whole_pipeline/int_only/dead_condition.c": {"return_code": 10}, "chapter_19/whole_pipeline/int_only/elim_and_copy_prop.c": {"return_code": 10}, "chapter_19/whole_pipeline/int_only/remainder_test.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/mixed_ints.c": {"return_code": 9}, "chapter_20/all_types/no_coalescing/dbl_trivially_colorable.c": {"return_code": 3}, "chapter_20/all_types/no_coalescing/spill_movz_dst.c": {"return_code": 29}, "chapter_20/all_types/no_coalescing/push_xmm.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/dbl_fun_call.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/stack_alignment.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/track_dbl_arg_registers.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/fourteen_pseudos_interfere.c": {"return_code": 0}, "chapter_20/all_types/no_coalescing/div_interference.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/test_spilling_dbls.c": {"return_code": 3}, "chapter_20/all_types/no_coalescing/store_pointer_in_register.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/same_instr_interference.c": {"return_code": 6}, "chapter_20/int_only/no_coalescing/spills_rewrites_compare.c": {"return_code": 3}, "chapter_20/int_only/no_coalescing/copy_and_separate_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/spills_and_rewrites.c": {"return_code": 23}, "chapter_20/int_only/no_coalescing/cmp_liveness.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/rewrite_large_multiply.c": {"return_code": 58}, "chapter_20/int_only/no_coalescing/spill_callee_saved.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/test_spill_metric.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/unary_interference.c": {"return_code": 10}, "chapter_20/int_only/no_coalescing/optimistic_coloring.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/track_arg_registers.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/many_pseudos_fewer_conflicts.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/same_instr_no_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/copy_no_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/force_spill.c": {"return_code": 9}, "chapter_20/int_only/no_coalescing/callee_saved_stack_alignment.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/idiv_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/preserve_across_fun_call.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/use_all_hardregs.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/test_spill_metric_2.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/loop.c": {"return_code": 6}, "chapter_20/int_only/no_coalescing/trivially_colorable.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/cdq_interference.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/cdq_generates_ax.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/callee_saved_live_at_exit.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/coalesce_prevents_spill.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/george_coalesce.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/unary_generates_dst.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/briggs_coalesce.c": {"return_code": 2}, "chapter_20/int_only/with_coalescing/bin_generates_dst.c": {"return_code": 187}, "chapter_20/int_only/with_coalescing/briggs_coalesce_tmps.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/cmp_generates_operands.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/funcall_generates_args.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/eax_live_at_exit.c": {"return_code": 1}, "chapter_19/dead_store_elimination/int_only/static_not_always_live.c": {"return_code": 23}, "chapter_19/dead_store_elimination/int_only/fig_19_11.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/delete_arithmetic_ops.c": {"return_code": 5}, "chapter_19/dead_store_elimination/int_only/initialize_blocks_with_empty_set.c": {"return_code": 1}, "chapter_19/dead_store_elimination/int_only/dont_elim/self_copy.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/dont_elim/recognize_all_uses.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/dont_elim/nested_loops.c": {"return_code": 0, "stdout": "DKHEB"}, "chapter_19/dead_store_elimination/all_types/delete_dead_pt_ii_instructions.c": {"return_code": 5}, "chapter_19/dead_store_elimination/all_types/dont_elim/funcall_generates_aliased.c": {"return_code": 4}, "chapter_19/dead_store_elimination/all_types/dont_elim/use_and_update.c": {"return_code": 1}, "chapter_19/dead_store_elimination/all_types/dont_elim/recognize_all_uses.c": {"return_code": 0}, "chapter_19/dead_store_elimination/all_types/dont_elim/load_generates_aliased.c": {"return_code": 10}} \ No newline at end of file +{"chapter_6/valid/rh_assignment.c": {"return_code": 1}, "chapter_6/valid/if_nested_2.c": {"return_code": 2}, "chapter_6/valid/if_nested_3.c": {"return_code": 3}, "chapter_6/valid/nested_ternary.c": {"return_code": 7}, "chapter_6/valid/binary_false_condition.c": {"return_code": 0}, "chapter_6/valid/else.c": {"return_code": 2}, "chapter_6/valid/nested_ternary_2.c": {"return_code": 15}, "chapter_6/valid/ternary_short_circuit.c": {"return_code": 1}, "chapter_6/valid/multiple_if.c": {"return_code": 8}, "chapter_6/valid/if_null_body.c": {"return_code": 1}, "chapter_6/valid/ternary_rh_binop.c": {"return_code": 1}, "chapter_6/valid/ternary_middle_assignment.c": {"return_code": 2}, "chapter_6/valid/if_nested_4.c": {"return_code": 4}, "chapter_6/valid/ternary_middle_binop.c": {"return_code": 1}, "chapter_6/valid/if_taken.c": {"return_code": 1}, "chapter_6/valid/if_not_taken.c": {"return_code": 0}, "chapter_6/valid/if_nested_5.c": {"return_code": 1}, "chapter_6/valid/assign_ternary.c": {"return_code": 2}, "chapter_6/valid/ternary.c": {"return_code": 4}, "chapter_6/valid/if_nested.c": {"return_code": 1}, "chapter_6/valid/ternary_short_circuit_2.c": {"return_code": 2}, "chapter_6/valid/binary_condition.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_and_var.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_main_2.c": {"return_code": 0}, "chapter_6/valid/extra_credit/bitwise_ternary.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_main.c": {"return_code": 0}, "chapter_6/valid/extra_credit/goto_nested_label.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_backwards.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label.c": {"return_code": 1}, "chapter_6/valid/extra_credit/compound_if_expression.c": {"return_code": 1}, "chapter_6/valid/extra_credit/goto_after_declaration.c": {"return_code": 1}, "chapter_8/valid/for.c": {"return_code": 16}, "chapter_8/valid/continue.c": {"return_code": 1}, "chapter_8/valid/multi_continue_same_loop.c": {"return_code": 1}, "chapter_8/valid/for_absent_post.c": {"return_code": 0}, "chapter_8/valid/null_for_header.c": {"return_code": 4}, "chapter_8/valid/nested_loop.c": {"return_code": 1}, "chapter_8/valid/nested_break.c": {"return_code": 250}, "chapter_8/valid/do_while.c": {"return_code": 16}, "chapter_8/valid/for_absent_condition.c": {"return_code": 0}, "chapter_8/valid/do_while_break_immediate.c": {"return_code": 10}, "chapter_8/valid/continue_empty_post.c": {"return_code": 30}, "chapter_8/valid/nested_continue.c": {"return_code": 24}, "chapter_8/valid/break.c": {"return_code": 1}, "chapter_8/valid/for_nested_shadow.c": {"return_code": 1}, "chapter_8/valid/empty_expression.c": {"return_code": 0}, "chapter_8/valid/multi_break.c": {"return_code": 1}, "chapter_8/valid/for_decl.c": {"return_code": 101}, "chapter_8/valid/for_shadow.c": {"return_code": 1}, "chapter_8/valid/break_immediate.c": {"return_code": 1}, "chapter_8/valid/while.c": {"return_code": 6}, "chapter_8/valid/empty_loop_body.c": {"return_code": 252}, "chapter_8/valid/extra_credit/switch_fallthrough.c": {"return_code": 4}, "chapter_8/valid/extra_credit/compound_assignment_for_loop.c": {"return_code": 10}, "chapter_8/valid/extra_credit/switch_break.c": {"return_code": 5}, "chapter_8/valid/extra_credit/switch_default.c": {"return_code": 22}, "chapter_8/valid/extra_credit/switch_default_fallthrough.c": {"return_code": 0}, "chapter_8/valid/extra_credit/switch_with_loop.c": {"return_code": 123}, "chapter_8/valid/extra_credit/switch_assign_in_body.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_in_loop.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_no_case.c": {"return_code": 4}, "chapter_8/valid/extra_credit/switch_nested_case.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_nested_not_taken.c": {"return_code": 2}, "chapter_8/valid/extra_credit/switch_decl.c": {"return_code": 7}, "chapter_8/valid/extra_credit/switch_with_continue.c": {"return_code": 5}, "chapter_8/valid/extra_credit/switch_empty.c": {"return_code": 10}, "chapter_8/valid/extra_credit/goto_loop_body.c": {"return_code": 1}, "chapter_8/valid/extra_credit/goto_bypass_condition.c": {"return_code": 10}, "chapter_8/valid/extra_credit/switch_nested_switch.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_block.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_default_not_last.c": {"return_code": 0}, "chapter_8/valid/extra_credit/switch_assign_in_condition.c": {"return_code": 2}, "chapter_8/valid/extra_credit/switch.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_goto_mid_case.c": {"return_code": 1}, "chapter_14/valid/libraries/static_pointer.c": {"return_code": 0}, "chapter_14/valid/libraries/global_pointer.c": {"return_code": 1}, "chapter_14/valid/function_calls/address_of_argument.c": {"return_code": 0}, "chapter_14/valid/function_calls/update_value_through_pointer_parameter.c": {"return_code": 0}, "chapter_14/valid/function_calls/return_pointer.c": {"return_code": 0}, "chapter_14/valid/extra_credit/incr_through_pointer.c": {"return_code": 11}, "chapter_14/valid/extra_credit/compound_assign_through_pointer.c": {"return_code": 1}, "chapter_14/valid/declarators/declare_pointer_in_for_loop.c": {"return_code": 5}, "chapter_14/valid/declarators/abstract_declarators.c": {"return_code": 0}, "chapter_14/valid/declarators/declarators.c": {"return_code": 0}, "chapter_14/valid/dereference/static_var_indirection.c": {"return_code": 0}, "chapter_14/valid/dereference/multilevel_indirection.c": {"return_code": 0}, "chapter_14/valid/dereference/read_through_pointers.c": {"return_code": 0}, "chapter_14/valid/dereference/update_through_pointers.c": {"return_code": 0}, "chapter_14/valid/dereference/address_of_dereference.c": {"return_code": 0}, "chapter_14/valid/dereference/simple.c": {"return_code": 3}, "chapter_14/valid/dereference/dereference_expression_result.c": {"return_code": 0}, "chapter_14/valid/casts/cast_between_pointer_types.c": {"return_code": 0}, "chapter_14/valid/casts/pointer_int_casts.c": {"return_code": 0}, "chapter_14/valid/casts/null_pointer_conversion.c": {"return_code": 0}, "chapter_14/valid/comparisons/compare_pointers.c": {"return_code": 0}, "chapter_14/valid/comparisons/pointers_as_conditions.c": {"return_code": 0}, "chapter_14/valid/comparisons/compare_to_null.c": {"return_code": 0}, "chapter_10/valid/static_then_extern.c": {"return_code": 3}, "chapter_10/valid/push_arg_on_page_boundary.c": {"return_code": 1}, "chapter_10/valid/static_local_multiple_scopes.c": {"return_code": 0, "stdout": "Aa\nBb\nCc\nDd\nEe\nFf\nGg\nHh\nIi\nJj\nKk\nLl\nMm\nNn\nOo\nPp\nQq\nRr\nSs\nTt\nUu\nVv\nWw\nXx\nYy\nZz\n"}, "chapter_10/valid/tentative_definition.c": {"return_code": 5}, "chapter_10/valid/static_variables_in_expressions.c": {"return_code": 0}, "chapter_10/valid/static_recursive_call.c": {"return_code": 0, "stdout": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, "chapter_10/valid/shadow_static_local_var.c": {"return_code": 0}, "chapter_10/valid/multiple_static_local.c": {"return_code": 29}, "chapter_10/valid/multiple_static_file_scope_vars.c": {"return_code": 4}, "chapter_10/valid/static_local_uninitialized.c": {"return_code": 4}, "chapter_10/valid/type_before_storage_class.c": {"return_code": 7}, "chapter_10/valid/extern_block_scope_variable.c": {"return_code": 3}, "chapter_10/valid/distinct_local_and_extern.c": {"return_code": 7}, "chapter_10/valid/libraries/internal_hides_external_linkage.c": {"return_code": 0}, "chapter_10/valid/libraries/external_tentative_var.c": {"return_code": 0}, "chapter_10/valid/libraries/external_linkage_function.c": {"return_code": 0}, "chapter_10/valid/libraries/external_variable.c": {"return_code": 0}, "chapter_10/valid/libraries/internal_linkage_var.c": {"return_code": 0}, "chapter_10/valid/libraries/external_var_scoping.c": {"return_code": 0}, "chapter_10/valid/libraries/internal_linkage_function.c": {"return_code": 0}, "chapter_10/valid/extra_credit/goto_skip_static_initializer.c": {"return_code": 10}, "chapter_2/valid/neg.c": {"return_code": 251}, "chapter_2/valid/negate_int_max.c": {"return_code": 1}, "chapter_2/valid/redundant_parens.c": {"return_code": 246}, "chapter_2/valid/neg_zero.c": {"return_code": 0}, "chapter_2/valid/bitwise_int_min.c": {"return_code": 254}, "chapter_2/valid/bitwise_zero.c": {"return_code": 255}, "chapter_2/valid/parens_3.c": {"return_code": 4}, "chapter_2/valid/parens_2.c": {"return_code": 253}, "chapter_2/valid/bitwise.c": {"return_code": 243}, "chapter_2/valid/nested_ops_2.c": {"return_code": 1}, "chapter_2/valid/nested_ops.c": {"return_code": 2}, "chapter_2/valid/parens.c": {"return_code": 254}, "chapter_1/valid/return_0.c": {"return_code": 0}, "chapter_1/valid/newlines.c": {"return_code": 0}, "chapter_1/valid/return_2.c": {"return_code": 2}, "chapter_1/valid/multi_digit.c": {"return_code": 100}, "chapter_1/valid/tabs.c": {"return_code": 0}, "chapter_1/valid/spaces.c": {"return_code": 0}, "chapter_1/valid/no_newlines.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/logical.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/static_initialized_double.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/comparisons.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/simple.c": {"return_code": 1}, "chapter_13/valid/floating_expressions/loop_controlling_expression.c": {"return_code": 100}, "chapter_13/valid/libraries/double_parameters.c": {"return_code": 0}, "chapter_13/valid/libraries/use_arg_after_fun_call.c": {"return_code": 4}, "chapter_13/valid/libraries/double_and_int_params_recursive.c": {"return_code": 0}, "chapter_13/valid/libraries/extern_double.c": {"return_code": 1}, "chapter_13/valid/libraries/double_params_and_result.c": {"return_code": 1}, "chapter_13/valid/explicit_casts/cvttsd2i_rewrite.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/double_to_signed.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/unsigned_to_double.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/signed_to_double.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/double_to_unsigned.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/convert_for_assignment.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/static_initializers.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/complex_arithmetic_common_type.c": {"return_code": 1}, "chapter_13/valid/constants/round_constants.c": {"return_code": 0}, "chapter_13/valid/constants/constant_doubles.c": {"return_code": 0}, "chapter_13/valid/special_values/subnormal_not_zero.c": {"return_code": 0}, "chapter_13/valid/special_values/negative_zero.c": {"return_code": 0}, "chapter_13/valid/special_values/infinity.c": {"return_code": 0}, "chapter_13/valid/function_calls/double_parameters.c": {"return_code": 0}, "chapter_13/valid/function_calls/double_and_int_parameters.c": {"return_code": 0}, "chapter_13/valid/function_calls/standard_library_call.c": {"return_code": 0}, "chapter_13/valid/function_calls/use_arg_after_fun_call.c": {"return_code": 4}, "chapter_13/valid/function_calls/return_double.c": {"return_code": 1}, "chapter_13/valid/function_calls/double_and_int_params_recursive.c": {"return_code": 0}, "chapter_13/valid/extra_credit/compound_assign.c": {"return_code": 1}, "chapter_13/valid/extra_credit/nan.c": {"return_code": 0}, "chapter_13/valid/extra_credit/compound_assign_implicit_cast.c": {"return_code": 1}, "chapter_18/valid/params_and_returns/temporary_lifetime.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/ignore_retval.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_space_overlap.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_big_struct_on_page_boundary.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/simple.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_struct_on_page_boundary.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_incomplete_type.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/stack_clobber.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/libraries/missing_retval.c": {"return_code": 1}, "chapter_18/valid/params_and_returns/libraries/access_retval_members.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/semantic_analysis/resolve_tags.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/semantic_analysis/namespaces.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/semantic_analysis/incomplete_structs.c": {"return_code": 0, "stdout": "I'm a struct!\n"}, "chapter_18/valid/no_structure_parameters/semantic_analysis/cast_struct_to_void.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/global_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/param_struct_pointer.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/return_struct_pointer.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/opaque_struct.c": {"return_code": 0, "stdout": "new struct\nstatic struct\nglobal struct\n"}, "chapter_18/valid/no_structure_parameters/libraries/array_of_structs.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/auto_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/static_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/nested_static_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/nested_auto_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/smoke_tests/static_vs_auto.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/smoke_tests/simple.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/member_offsets.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/sizeof_exps.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/sizeof_type.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/arrow.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/linked_list.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/static_structs.c": {"return_code": 0, "stdout": "zero\nmn\nop\nwx\nyz\nBCD\nCDE\nDEF\nEFG\nbcd\ncde\n"}, "chapter_18/valid/no_structure_parameters/scalar_member_access/nested_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/dot.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/parse_and_lex/postfix_precedence.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/parse_and_lex/trailing_comma.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/parse_and_lex/space_around_struct_member.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/parse_and_lex/struct_member_looks_like_const.c": {"return_code": 3}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_with_arrow_operator.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/stack_clobber.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_with_dot_operator.c": {"return_code": 0}, "chapter_18/valid/parameters/pass_args_on_page_boundary.c": {"return_code": 0}, "chapter_18/valid/parameters/incomplete_param_type.c": {"return_code": 3}, "chapter_18/valid/parameters/simple.c": {"return_code": 0}, "chapter_18/valid/parameters/stack_clobber.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/param_calling_conventions.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/struct_sizes.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/pass_struct.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/modify_param.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/classify_params.c": {"return_code": 0}, "chapter_15/valid/initialization/automatic.c": {"return_code": 0}, "chapter_15/valid/initialization/static.c": {"return_code": 0}, "chapter_15/valid/initialization/trailing_comma_initializer.c": {"return_code": 3}, "chapter_15/valid/initialization/automatic_nested.c": {"return_code": 0}, "chapter_15/valid/initialization/static_nested.c": {"return_code": 0}, "chapter_15/valid/libraries/set_array_val.c": {"return_code": 0}, "chapter_15/valid/libraries/return_pointer_to_array.c": {"return_code": 0}, "chapter_15/valid/libraries/global_array.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_nested.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_pointer.c": {"return_code": 0}, "chapter_15/valid/subscripting/array_of_pointers_to_arrays.c": {"return_code": 0}, "chapter_15/valid/subscripting/simple_subscripts.c": {"return_code": 0}, "chapter_15/valid/subscripting/simple.c": {"return_code": 3}, "chapter_15/valid/subscripting/complex_operands.c": {"return_code": 0}, "chapter_15/valid/subscripting/addition_subscript_equivalence.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_precedence.c": {"return_code": 1}, "chapter_15/valid/allocation/test_alignment.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/pointer_add.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/add_dereference_and_assign.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/pointer_diff.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/compare.c": {"return_code": 0}, "chapter_15/valid/extra_credit/incr_ptr.c": {"return_code": 1}, "chapter_15/valid/declarators/big_array.c": {"return_code": 0}, "chapter_15/valid/declarators/equivalent_declarators.c": {"return_code": 0}, "chapter_15/valid/declarators/return_nested_array.c": {"return_code": 0}, "chapter_15/valid/declarators/array_as_argument.c": {"return_code": 0}, "chapter_15/valid/declarators/for_loop_array.c": {"return_code": 0}, "chapter_15/valid/casts/multi_dim_casts.c": {"return_code": 0}, "chapter_15/valid/casts/implicit_and_explicit_conversions.c": {"return_code": 0}, "chapter_15/valid/casts/cast_array_of_pointers.c": {"return_code": 1}, "chapter_17/valid/void/cast_to_void.c": {"return_code": 12}, "chapter_17/valid/void/void_function.c": {"return_code": 0}, "chapter_17/valid/void/void_for_loop.c": {"return_code": 0, "stdout": "ZYXWVUTSRQPONMLKJIHGFEDCBAABCDEFGHIJKLMNOPQRSTUVWXYZZYXWVUTSRQPONMLKJIHGFEDCBA"}, "chapter_17/valid/void/ternary.c": {"return_code": 0}, "chapter_17/valid/libraries/pass_alloced_memory.c": {"return_code": 0}, "chapter_17/valid/libraries/test_for_memory_leaks.c": {"return_code": 0}, "chapter_17/valid/libraries/sizeof_extern.c": {"return_code": 1}, "chapter_17/valid/sizeof/sizeof_basic_types.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_consts.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_expressions.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_array.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_derived_types.c": {"return_code": 0}, "chapter_17/valid/sizeof/simple.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_result_is_ulong.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_not_evaluated.c": {"return_code": 4}, "chapter_17/valid/void_pointer/array_of_pointers_to_void.c": {"return_code": 0}, "chapter_17/valid/void_pointer/conversion_by_assignment.c": {"return_code": 0}, "chapter_17/valid/void_pointer/explicit_cast.c": {"return_code": 0}, "chapter_17/valid/void_pointer/simple.c": {"return_code": 100}, "chapter_17/valid/void_pointer/memory_management_functions.c": {"return_code": 0}, "chapter_17/valid/void_pointer/common_pointer_type.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/addr_of_string.c": {"return_code": 0, "stdout": "Sample\tstring!\n\n"}, "chapter_16/valid/strings_as_lvalues/standard_library_calls.c": {"return_code": 0, "stdout": "Hello, World!\n"}, "chapter_16/valid/strings_as_lvalues/array_of_strings.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/cast_string_pointer.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/empty_string.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/pointer_operations.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/simple.c": {"return_code": 108}, "chapter_16/valid/strings_as_lvalues/adjacent_strings.c": {"return_code": 0, "stdout": "Hello, World\n"}, "chapter_16/valid/strings_as_lvalues/string_special_characters.c": {"return_code": 0, "stdout": "Hello\"world\nHello\\World\nLine\nbreak!\nTesting, 123.\n^@1 _\\]\n"}, "chapter_16/valid/strings_as_lvalues/strings_in_function_calls.c": {"return_code": 0}, "chapter_16/valid/libraries/return_char.c": {"return_code": 0}, "chapter_16/valid/libraries/char_arguments.c": {"return_code": 0}, "chapter_16/valid/libraries/global_char.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/array_init_special_chars.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/terminating_null_bytes.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/simple.c": {"return_code": 99}, "chapter_16/valid/strings_as_initializers/partial_initialize_via_string.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/adjacent_strings_in_initializer.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/transfer_by_eightbyte.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/literals_and_compound_initializers.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/write_to_array.c": {"return_code": 0, "stdout": "abc\nabx\nHello\nWorld\nJello\n"}, "chapter_16/valid/strings_as_initializers/test_alignment.c": {"return_code": 0}, "chapter_16/valid/char_constants/return_char_constant.c": {"return_code": 99}, "chapter_16/valid/char_constants/escape_sequences.c": {"return_code": 0}, "chapter_16/valid/char_constants/control_characters.c": {"return_code": 0}, "chapter_16/valid/char_constants/char_constant_operations.c": {"return_code": 0}, "chapter_16/valid/chars/partial_initialization.c": {"return_code": 0}, "chapter_16/valid/chars/convert_by_assignment.c": {"return_code": 0}, "chapter_16/valid/chars/type_specifiers.c": {"return_code": 0}, "chapter_16/valid/chars/push_arg_on_page_boundary.c": {"return_code": 1}, "chapter_16/valid/chars/integer_promotion.c": {"return_code": 0}, "chapter_16/valid/chars/chained_casts.c": {"return_code": 0}, "chapter_16/valid/chars/return_char.c": {"return_code": 0}, "chapter_16/valid/chars/char_arguments.c": {"return_code": 0}, "chapter_16/valid/chars/char_expressions.c": {"return_code": 0}, "chapter_16/valid/chars/access_through_char_pointer.c": {"return_code": 0}, "chapter_16/valid/chars/common_type.c": {"return_code": 0}, "chapter_16/valid/chars/static_initializers.c": {"return_code": 0}, "chapter_16/valid/chars/explicit_casts.c": {"return_code": 0}, "chapter_9/valid/arguments_in_registers/parameter_shadows_own_function.c": {"return_code": 2}, "chapter_9/valid/arguments_in_registers/expression_args.c": {"return_code": 2}, "chapter_9/valid/arguments_in_registers/single_arg.c": {"return_code": 6}, "chapter_9/valid/arguments_in_registers/hello_world.c": {"return_code": 0, "stdout": "Hello, World!\n"}, "chapter_9/valid/arguments_in_registers/parameter_shadows_function.c": {"return_code": 3}, "chapter_9/valid/arguments_in_registers/parameters_are_preserved.c": {"return_code": 1}, "chapter_9/valid/arguments_in_registers/forward_decl_multi_arg.c": {"return_code": 1}, "chapter_9/valid/arguments_in_registers/fibonacci.c": {"return_code": 8}, "chapter_9/valid/arguments_in_registers/param_shadows_local_var.c": {"return_code": 20}, "chapter_9/valid/no_arguments/function_shadows_variable.c": {"return_code": 11}, "chapter_9/valid/no_arguments/use_function_in_expression.c": {"return_code": 21}, "chapter_9/valid/no_arguments/no_return_value.c": {"return_code": 3}, "chapter_9/valid/no_arguments/multiple_declarations.c": {"return_code": 3}, "chapter_9/valid/no_arguments/precedence.c": {"return_code": 0}, "chapter_9/valid/no_arguments/forward_decl.c": {"return_code": 3}, "chapter_9/valid/no_arguments/variable_shadows_function.c": {"return_code": 7}, "chapter_9/valid/libraries/system_call.c": {"return_code": 0, "stdout": "H"}, "chapter_9/valid/libraries/many_args.c": {"return_code": 115}, "chapter_9/valid/libraries/addition.c": {"return_code": 3}, "chapter_9/valid/libraries/no_function_calls/division.c": {"return_code": 1}, "chapter_9/valid/libraries/no_function_calls/local_stack_variables.c": {"return_code": 100}, "chapter_9/valid/extra_credit/compound_assign_function_result.c": {"return_code": 1}, "chapter_9/valid/extra_credit/goto_label_multiple_functions.c": {"return_code": 5}, "chapter_9/valid/extra_credit/goto_shared_name.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/call_putchar.c": {"return_code": 8, "stdout": "A"}, "chapter_9/valid/stack_arguments/lots_of_arguments.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/stack_alignment.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/test_for_memory_leaks.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/logical.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/arithmetic_wraparound.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/comparisons.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/simple.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/static_variables.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/locals.c": {"return_code": 0}, "chapter_12/valid/libraries/unsigned_args.c": {"return_code": 0}, "chapter_12/valid/libraries/unsigned_global_var.c": {"return_code": 1}, "chapter_12/valid/explicit_casts/same_size_conversion.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/extension.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/round_trip_casts.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/chained_casts.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/truncate.c": {"return_code": 0}, "chapter_12/valid/type_specifiers/signed_type_specifiers.c": {"return_code": 0}, "chapter_12/valid/type_specifiers/unsigned_type_specifiers.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/convert_by_assignment.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/promote_constants.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/static_initializers.c": {"return_code": 0}, "chapter_12/valid/extra_credit/switch_uint.c": {"return_code": 0}, "chapter_12/valid/extra_credit/compound_assign_uint.c": {"return_code": 1}, "chapter_12/valid/extra_credit/bitwise_unsigned_shift.c": {"return_code": 1}, "chapter_12/valid/extra_credit/bitwise_unsigned_ops.c": {"return_code": 1}, "chapter_5/valid/null_then_return.c": {"return_code": 0}, "chapter_5/valid/empty_function_body.c": {"return_code": 0}, "chapter_5/valid/short_circuit_or.c": {"return_code": 0}, "chapter_5/valid/assignment_in_initializer.c": {"return_code": 0}, "chapter_5/valid/non_short_circuit_or.c": {"return_code": 1}, "chapter_5/valid/null_statement.c": {"return_code": 0}, "chapter_5/valid/short_circuit_and_fail.c": {"return_code": 0}, "chapter_5/valid/local_var_missing_return.c": {"return_code": 0}, "chapter_5/valid/exp_then_declaration.c": {"return_code": 1}, "chapter_5/valid/add_variables.c": {"return_code": 3}, "chapter_5/valid/assign_val_in_initializer.c": {"return_code": 5}, "chapter_5/valid/assignment_lowest_precedence.c": {"return_code": 1}, "chapter_5/valid/allocate_temps_and_vars.c": {"return_code": 1}, "chapter_5/valid/use_assignment_result.c": {"return_code": 4}, "chapter_5/valid/use_val_in_own_initializer.c": {"return_code": 0}, "chapter_5/valid/unused_exp.c": {"return_code": 0}, "chapter_5/valid/return_var.c": {"return_code": 2}, "chapter_5/valid/mixed_precedence_assignment.c": {"return_code": 4}, "chapter_5/valid/assign.c": {"return_code": 2}, "chapter_5/valid/extra_credit/bitwise_shiftr_assign.c": {"return_code": 77}, "chapter_5/valid/extra_credit/bitwise_shiftl_variable.c": {"return_code": 24}, "chapter_5/valid/extra_credit/compound_bitwise_and.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_minus.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_multiply.c": {"return_code": 12}, "chapter_5/valid/extra_credit/compound_bitwise_xor.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_bitwise_or.c": {"return_code": 31}, "chapter_5/valid/extra_credit/compound_assignment_chained.c": {"return_code": 4}, "chapter_5/valid/extra_credit/compound_divide.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_bitwise_shiftr.c": {"return_code": 102}, "chapter_5/valid/extra_credit/compound_assignment_use_result.c": {"return_code": 8}, "chapter_5/valid/extra_credit/compound_bitwise_shiftl.c": {"return_code": 48}, "chapter_5/valid/extra_credit/compound_plus.c": {"return_code": 4}, "chapter_5/valid/extra_credit/compound_mod.c": {"return_code": 2}, "chapter_5/valid/extra_credit/bitwise_and_vars.c": {"return_code": 1}, "chapter_7/valid/declaration_only.c": {"return_code": 1}, "chapter_7/valid/assign_to_self_2.c": {"return_code": 3}, "chapter_7/valid/hidden_then_visible.c": {"return_code": 1}, "chapter_7/valid/hidden_variable.c": {"return_code": 1}, "chapter_7/valid/assign_to_self.c": {"return_code": 4}, "chapter_7/valid/inner_uninitialized.c": {"return_code": 4}, "chapter_7/valid/multiple_vars_same_name.c": {"return_code": 2}, "chapter_7/valid/use_in_inner_scope.c": {"return_code": 3}, "chapter_7/valid/empty_blocks.c": {"return_code": 30}, "chapter_7/valid/nested_if.c": {"return_code": 1}, "chapter_7/valid/similar_var_names.c": {"return_code": 28}, "chapter_7/valid/extra_credit/goto_before_declaration.c": {"return_code": 0}, "chapter_7/valid/extra_credit/compound_subtract_in_block.c": {"return_code": 1}, "chapter_7/valid/extra_credit/goto_inner_scope.c": {"return_code": 1}, "chapter_4/valid/le_true.c": {"return_code": 2}, "chapter_4/valid/ne_true.c": {"return_code": 1}, "chapter_4/valid/ge_false.c": {"return_code": 0}, "chapter_4/valid/not_zero.c": {"return_code": 1}, "chapter_4/valid/precedence_2.c": {"return_code": 0}, "chapter_4/valid/ge_true.c": {"return_code": 2}, "chapter_4/valid/eq_precedence.c": {"return_code": 1}, "chapter_4/valid/eq_false.c": {"return_code": 0}, "chapter_4/valid/or_short_circuit.c": {"return_code": 1}, "chapter_4/valid/not_sum.c": {"return_code": 1}, "chapter_4/valid/precedence_4.c": {"return_code": 1}, "chapter_4/valid/and_short_circuit.c": {"return_code": 0}, "chapter_4/valid/precedence_3.c": {"return_code": 0}, "chapter_4/valid/compare_arithmetic_results.c": {"return_code": 1}, "chapter_4/valid/and_false.c": {"return_code": 0}, "chapter_4/valid/precedence_5.c": {"return_code": 1}, "chapter_4/valid/associativity.c": {"return_code": 1}, "chapter_4/valid/gt_true.c": {"return_code": 1}, "chapter_4/valid/lt_false.c": {"return_code": 0}, "chapter_4/valid/or_true.c": {"return_code": 3}, "chapter_4/valid/or_false.c": {"return_code": 0}, "chapter_4/valid/eq_true.c": {"return_code": 1}, "chapter_4/valid/ne_false.c": {"return_code": 0}, "chapter_4/valid/multi_short_circuit.c": {"return_code": 0}, "chapter_4/valid/gt_false.c": {"return_code": 0}, "chapter_4/valid/operate_on_booleans.c": {"return_code": 0}, "chapter_4/valid/not.c": {"return_code": 0}, "chapter_4/valid/le_false.c": {"return_code": 0}, "chapter_4/valid/nested_ops.c": {"return_code": 0}, "chapter_4/valid/precedence.c": {"return_code": 1}, "chapter_4/valid/not_sum_2.c": {"return_code": 0}, "chapter_4/valid/and_true.c": {"return_code": 1}, "chapter_4/valid/lt_true.c": {"return_code": 1}, "chapter_4/valid/extra_credit/bitwise_precedence.c": {"return_code": 1}, "chapter_3/valid/mod.c": {"return_code": 0}, "chapter_3/valid/unop_add.c": {"return_code": 0}, "chapter_3/valid/associativity_3.c": {"return_code": 8}, "chapter_3/valid/mult.c": {"return_code": 6}, "chapter_3/valid/sub.c": {"return_code": 255}, "chapter_3/valid/div_neg.c": {"return_code": 254}, "chapter_3/valid/unop_parens.c": {"return_code": 253}, "chapter_3/valid/add.c": {"return_code": 3}, "chapter_3/valid/associativity.c": {"return_code": 252}, "chapter_3/valid/associativity_2.c": {"return_code": 1}, "chapter_3/valid/div.c": {"return_code": 2}, "chapter_3/valid/sub_neg.c": {"return_code": 3}, "chapter_3/valid/associativity_and_precedence.c": {"return_code": 10}, "chapter_3/valid/parens.c": {"return_code": 14}, "chapter_3/valid/precedence.c": {"return_code": 14}, "chapter_3/valid/extra_credit/bitwise_shiftr.c": {"return_code": 62}, "chapter_3/valid/extra_credit/bitwise_and.c": {"return_code": 1}, "chapter_3/valid/extra_credit/bitwise_shiftl.c": {"return_code": 140}, "chapter_3/valid/extra_credit/bitwise_or.c": {"return_code": 3}, "chapter_3/valid/extra_credit/bitwise_shift_precedence.c": {"return_code": 0}, "chapter_3/valid/extra_credit/bitwise_xor.c": {"return_code": 6}, "chapter_3/valid/extra_credit/bitwise_shift_associativity_2.c": {"return_code": 16}, "chapter_3/valid/extra_credit/bitwise_shift_associativity.c": {"return_code": 66}, "chapter_3/valid/extra_credit/bitwise_precedence.c": {"return_code": 21}, "chapter_11/valid/long_expressions/long_args.c": {"return_code": 0}, "chapter_11/valid/long_expressions/logical.c": {"return_code": 0}, "chapter_11/valid/long_expressions/type_specifiers.c": {"return_code": 0}, "chapter_11/valid/long_expressions/multi_op.c": {"return_code": 1}, "chapter_11/valid/long_expressions/large_constants.c": {"return_code": 0}, "chapter_11/valid/long_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_11/valid/long_expressions/return_long.c": {"return_code": 1}, "chapter_11/valid/long_expressions/comparisons.c": {"return_code": 0}, "chapter_11/valid/long_expressions/simple.c": {"return_code": 1}, "chapter_11/valid/long_expressions/static_long.c": {"return_code": 1}, "chapter_11/valid/long_expressions/long_and_int_locals.c": {"return_code": 0}, "chapter_11/valid/long_expressions/assign.c": {"return_code": 1}, "chapter_11/valid/libraries/long_args.c": {"return_code": 0}, "chapter_11/valid/libraries/maintain_stack_alignment.c": {"return_code": 12}, "chapter_11/valid/libraries/return_long.c": {"return_code": 1}, "chapter_11/valid/libraries/long_global_var.c": {"return_code": 0}, "chapter_11/valid/explicit_casts/truncate.c": {"return_code": 0}, "chapter_11/valid/explicit_casts/sign_extend.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_by_assignment.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/long_constants.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_function_arguments.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_static_initializer.c": {"return_code": 0}, "chapter_11/valid/extra_credit/bitwise_long_op.c": {"return_code": 1}, "chapter_11/valid/extra_credit/compound_assign_to_int.c": {"return_code": 1}, "chapter_11/valid/extra_credit/compound_assign_to_long.c": {"return_code": 1}, "chapter_11/valid/extra_credit/switch_int.c": {"return_code": 1}, "chapter_11/valid/extra_credit/switch_long.c": {"return_code": 1}, "chapter_19/constant_folding/all_types/fold_truncate.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_cast_to_double.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_ulong.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_double.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_conditional_jump.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_extensions_and_copies.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/negative_zero.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_long.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_uint.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_cast_from_double.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_unary.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_conditional_jump.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_binary.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_control_flow.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_exception.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/remove_useless_starting_label.c": {"return_code": 99}, "chapter_19/unreachable_code_elimination/dead_for_loop.c": {"return_code": 10}, "chapter_19/unreachable_code_elimination/and_clause.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/keep_final_jump.c": {"return_code": 17}, "chapter_19/unreachable_code_elimination/remove_jump_keep_label.c": {"return_code": 10}, "chapter_19/unreachable_code_elimination/dead_branch_inside_loop.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/empty.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/infinite_loop.c": {"return_code": 11}, "chapter_19/unreachable_code_elimination/constant_if_else.c": {"return_code": 45}, "chapter_19/unreachable_code_elimination/dead_blocks_with_predecessors.c": {"return_code": 5}, "chapter_19/unreachable_code_elimination/remove_conditional_jumps.c": {"return_code": 1}, "chapter_19/unreachable_code_elimination/dead_after_return.c": {"return_code": 2}, "chapter_19/unreachable_code_elimination/empty_block.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/dead_after_if_else.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/or_clause.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/pointer_arithmetic.c": {"return_code": 2}, "chapter_19/copy_propagation/all_types/store_doesnt_kill.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/propagate_into_type_conversions.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/redundant_double_copies.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/char_type_conversion.c": {"return_code": 1, "stdout": "CBA@"}, "chapter_19/copy_propagation/all_types/alias_analysis.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/copy_struct.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/redundant_struct_copies.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/propagate_null_pointer.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/propagate_all_types.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/funcall_kills_aliased.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/static_are_aliased.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/store_kills_aliased.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/copy_to_offset.c": {"return_code": 3}, "chapter_19/copy_propagation/all_types/dont_propagate/dont_propagate_addr_of.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/type_conversion.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/dont_propagate/zero_neg_zero_different.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/killed_then_redefined.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/different_paths_same_copy.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/multi_path_no_kill.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/redundant_copies.c": {"return_code": 20}, "chapter_19/copy_propagation/int_only/fig_19_8.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/propagate_into_complex_expressions.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/propagate_static.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/propagate_static_var.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/kill_and_add_copies.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/init_all_copies.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/propagate_params.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/nested_loops.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/constant_propagation.c": {"return_code": 6}, "chapter_19/copy_propagation/int_only/propagate_var.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/different_source_values_same_copy.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/dont_propagate/source_killed_on_one_path.c": {"return_code": 0, "stdout": "DA"}, "chapter_19/copy_propagation/int_only/dont_propagate/one_reaching_copy.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/dont_propagate/dest_killed.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/no_copies_reach_entry.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/listing_19_14.c": {"return_code": 101}, "chapter_19/copy_propagation/int_only/dont_propagate/add_all_blocks_to_worklist.c": {"return_code": 100}, "chapter_19/copy_propagation/int_only/dont_propagate/multi_values.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/dont_propagate/static_dst_killed.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/dont_propagate/static_src_killed.c": {"return_code": 0}, "chapter_19/copy_propagation/int_only/dont_propagate/source_killed.c": {"return_code": 0}, "chapter_19/dead_store_elimination/all_types/aliased_dead_at_exit.c": {"return_code": 0}, "chapter_19/dead_store_elimination/all_types/getaddr_doesnt_gen.c": {"return_code": 0}, "chapter_19/dead_store_elimination/all_types/copy_to_dead_struct.c": {"return_code": 4}, "chapter_19/dead_store_elimination/all_types/delete_dead_pt_ii_instructions.c": {"return_code": 5}, "chapter_19/dead_store_elimination/all_types/dont_elim/funcall_generates_aliased.c": {"return_code": 4}, "chapter_19/dead_store_elimination/all_types/dont_elim/copytooffset_doesnt_kill.c": {"return_code": 0}, "chapter_19/dead_store_elimination/all_types/dont_elim/use_and_update.c": {"return_code": 1}, "chapter_19/dead_store_elimination/all_types/dont_elim/recognize_all_uses.c": {"return_code": 0}, "chapter_19/dead_store_elimination/all_types/dont_elim/never_kill_store.c": {"return_code": 4}, "chapter_19/dead_store_elimination/all_types/dont_elim/load_generates_aliased.c": {"return_code": 10}, "chapter_19/dead_store_elimination/int_only/static_not_always_live.c": {"return_code": 23}, "chapter_19/dead_store_elimination/int_only/fig_19_11.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/dead_store_static_var.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/loop_dead_store.c": {"return_code": 0, "stdout": "CHNTZ"}, "chapter_19/dead_store_elimination/int_only/simple.c": {"return_code": 3}, "chapter_19/dead_store_elimination/int_only/delete_arithmetic_ops.c": {"return_code": 5}, "chapter_19/dead_store_elimination/int_only/elim_second_copy.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/initialize_blocks_with_empty_set.c": {"return_code": 1}, "chapter_19/dead_store_elimination/int_only/dont_elim/self_copy.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/dont_elim/static_vars_at_exit.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/dont_elim/used_one_path.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/dont_elim/recognize_all_uses.c": {"return_code": 0}, "chapter_19/dead_store_elimination/int_only/dont_elim/dont_remove_funcall.c": {"return_code": 0, "stdout": "C"}, "chapter_19/dead_store_elimination/int_only/dont_elim/add_all_to_worklist.c": {"return_code": 0, "stdout": "ML"}, "chapter_19/dead_store_elimination/int_only/dont_elim/nested_loops.c": {"return_code": 0, "stdout": "DKHEB"}, "chapter_19/dead_store_elimination/int_only/dont_elim/loop.c": {"return_code": 1}, "chapter_19/dead_store_elimination/int_only/dont_elim/static_vars_fun.c": {"return_code": 5}, "chapter_19/whole_pipeline/all_types/fold_infinity.c": {"return_code": 0}, "chapter_19/whole_pipeline/all_types/fold_cast_to_double.c": {"return_code": 0}, "chapter_19/whole_pipeline/all_types/signed_unsigned_conversion.c": {"return_code": 0}, "chapter_19/whole_pipeline/all_types/alias_analysis_change.c": {"return_code": 0, "stdout": "A"}, "chapter_19/whole_pipeline/all_types/fold_char_condition.c": {"return_code": 0}, "chapter_19/whole_pipeline/all_types/fold_negative_zero.c": {"return_code": 0}, "chapter_19/whole_pipeline/all_types/fold_negative_values.c": {"return_code": 0}, "chapter_19/whole_pipeline/all_types/listing_19_5_more_types.c": {"return_code": 9}, "chapter_19/whole_pipeline/all_types/fold_cast_from_double.c": {"return_code": 0}, "chapter_19/whole_pipeline/all_types/fold_extension_and_truncation.c": {"return_code": 0}, "chapter_19/whole_pipeline/int_only/dead_condition.c": {"return_code": 10}, "chapter_19/whole_pipeline/int_only/listing_19_5.c": {"return_code": 9}, "chapter_19/whole_pipeline/int_only/elim_and_copy_prop.c": {"return_code": 10}, "chapter_19/whole_pipeline/int_only/remainder_test.c": {"return_code": 0}, "chapter_19/whole_pipeline/int_only/int_min.c": {"return_code": 0}, "chapter_20/all_types/no_coalescing/mixed_ints.c": {"return_code": 9}, "chapter_20/all_types/no_coalescing/dbl_trivially_colorable.c": {"return_code": 3}, "chapter_20/all_types/no_coalescing/spill_movz_dst.c": {"return_code": 29}, "chapter_20/all_types/no_coalescing/push_xmm.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/dbl_fun_call.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/stack_alignment.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/track_dbl_arg_registers.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/fourteen_pseudos_interfere.c": {"return_code": 0}, "chapter_20/all_types/no_coalescing/div_interference.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/test_spilling_dbls.c": {"return_code": 3}, "chapter_20/all_types/no_coalescing/store_pointer_in_register.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/same_instr_interference.c": {"return_code": 6}, "chapter_20/int_only/no_coalescing/spills_rewrites_compare.c": {"return_code": 3}, "chapter_20/int_only/no_coalescing/copy_and_separate_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/spills_and_rewrites.c": {"return_code": 23}, "chapter_20/int_only/no_coalescing/cmp_liveness.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/rewrite_large_multiply.c": {"return_code": 58}, "chapter_20/int_only/no_coalescing/spill_callee_saved.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/test_spill_metric.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/unary_interference.c": {"return_code": 10}, "chapter_20/int_only/no_coalescing/optimistic_coloring.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/track_arg_registers.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/many_pseudos_fewer_conflicts.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/same_instr_no_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/copy_no_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/force_spill.c": {"return_code": 9}, "chapter_20/int_only/no_coalescing/callee_saved_stack_alignment.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/idiv_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/preserve_across_fun_call.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/use_all_hardregs.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/test_spill_metric_2.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/loop.c": {"return_code": 6}, "chapter_20/int_only/no_coalescing/trivially_colorable.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/cdq_interference.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/cdq_generates_ax.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/callee_saved_live_at_exit.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/coalesce_prevents_spill.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/george_coalesce.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/unary_generates_dst.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/briggs_coalesce.c": {"return_code": 2}, "chapter_20/int_only/with_coalescing/bin_generates_dst.c": {"return_code": 187}, "chapter_20/int_only/with_coalescing/briggs_coalesce_tmps.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/cmp_generates_operands.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/funcall_generates_args.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/eax_live_at_exit.c": {"return_code": 1}, "chapter_19/whole_pipeline/all_types/integer_promotions.c": {"return_code": 0}} \ No newline at end of file diff --git a/test_framework/tacky/common.py b/test_framework/tacky/common.py index 9d6e3303..2fc5d272 100644 --- a/test_framework/tacky/common.py +++ b/test_framework/tacky/common.py @@ -23,7 +23,11 @@ class TackyOptimizationTest(basic.TestChapter): In the second kind of test, we still compile the program, run it, and validate its behavior, but we also inspect its assembly code to make sure it's been optimized. These test methods - should call run_and_parse, defined below. + should call run_and_parse or run_and_parse_all, defined below. + + This class defines two test methods used in dead store elimination and whole pipeline tests: + * store_eliminated_test: Test that stores of particular constants were eliminated + * return_const_test: Test that the only thing this function does is return a specific consatnt Notes: * This class isn't designed to test intermediate stages @@ -79,6 +83,8 @@ def store_eliminated_test( self, *, source_file: Path, redundant_consts: List[int] ) -> None: """Make sure any stores of the form mov $const, were eliminated. + + The test program should contain a single 'target' function. Args: source_file: absolute path to program under test redundant_consts: any constants that were sources of mov instructions in the @@ -110,7 +116,10 @@ def is_dead_store(i: asm.AsmItem) -> bool: ) def return_const_test(self, *, source_file: Path, returned_const: int) -> None: - """Validate that the function doesn't do anything except return a constant.""" + """Validate that the function doesn't do anything except return a constant. + + The test program should contain a single 'target' function. + """ def ok(i: asm.AsmItem) -> bool: """We should optimize out everything except prologue, epilogue, and mov into EAX""" diff --git a/test_framework/tacky/copy_prop.py b/test_framework/tacky/copy_prop.py index 61680eff..5f095125 100644 --- a/test_framework/tacky/copy_prop.py +++ b/test_framework/tacky/copy_prop.py @@ -217,7 +217,7 @@ def retval_test(self, expected_retval: Union[int, str], program_path: Path) -> N def arg_test( self, expected_args: Mapping[str, Sequence[Optional[int]]], program: Path ) -> None: - """Validate that propagate expected values into function arguments. + """Validate that we propagate expected values into function arguments. The copy propagation pass should be able to determine the constant values of some arguments to some function calls. Make sure we move these constants into @@ -227,7 +227,8 @@ def arg_test( * expected_args: mapping from function names to expected constant value of each argument. An argument's value is None if we don't expect to know it at compile time. - * program_path: absolute path to source file""" + * program_path: absolute path to source file + """ # convert constants to assembly operands expected_ops: Mapping[str, List[Optional[asm.Operand]]] = { @@ -366,18 +367,22 @@ def ok(i: asm.AsmItem) -> bool: # programs we'll validate with same_arg_test SAME_ARG_TESTS = [ - "store_doesnt_kill.c", - "copy_struct.c", + # int only "different_source_values_same_copy.c", "propagate_static_var.c", "propagate_var.c", "propagate_params.c", + # other types + "store_doesnt_kill.c", + "copy_struct.c", "char_type_conversion.c", ] # programs we'll validate with redundant_copies_test REDUNDANT_COPIES_TESTS = [ + # int only "redundant_copies.c", + # other types "redundant_double_copies.c", "redundant_struct_copies.c", ] diff --git a/test_framework/tacky/dead_store_elim.py b/test_framework/tacky/dead_store_elim.py index 7294da03..2621c8bd 100644 --- a/test_framework/tacky/dead_store_elim.py +++ b/test_framework/tacky/dead_store_elim.py @@ -18,8 +18,8 @@ class TestDeadStoreElimination(common.TackyOptimizationTest): Each dynamically generated test calls one of the following main test methods: * compile_and_run, defined in TestChapter: validate behavior but don't inspect assembly - * store_eliminated_test: make sure a particular mov instruction was eliminated - * return_const_test: make sure entire funcion is reduce to a return instruction + * store_eliminated_test, defined in TackyOptimizationTest: make sure a particular mov instruction was eliminated + * return_const_test, defined in TackyOptimizationTest: make sure entire funcion is reduce to a return instruction """ test_dir = common.TEST_DIR / "dead_store_elimination" @@ -42,7 +42,6 @@ class TestDeadStoreElimination(common.TackyOptimizationTest): # programs to validate with return_const_test, with expected return value RETURN_CONST = { - "self_copy.c": 5, "delete_arithmetic_ops.c": 5, "simple.c": 3, "delete_dead_pt_ii_instructions.c": 5, diff --git a/test_framework/tacky/pipeline.py b/test_framework/tacky/pipeline.py index 8d7bdef4..d8180f69 100644 --- a/test_framework/tacky/pipeline.py +++ b/test_framework/tacky/pipeline.py @@ -3,6 +3,15 @@ from pathlib import Path from typing import Callable +from ..parser.asm import ( + AsmItem, + Opcode, + Label, + Immediate, + Memory, + Register, + Instruction, +) from . import common @@ -13,20 +22,78 @@ class TestWholePipeline(common.TackyOptimizationTest): test_dir = common.TEST_DIR / "whole_pipeline" + def fold_const_test(self, *, source_file: Path) -> None: + """Constant folding should eliminate all computations from the target_* functions + + Similar to TackyOptimizationTest::return_const_test + but we allow any immediate (or RIP-relative operand, in case its a double) + rather than requiring a specific immediate + """ + + parsed_asm = self.run_and_parse_all(source_file) + + def ok(i: AsmItem) -> bool: + if common.is_prologue_or_epilogue(i): + return True + + # zeroing out EAX with xor is okay + if i == Instruction(Opcode.XOR, [Register.AX, Register.AX]): + return True + + if isinstance(i, Label) or i.opcode != Opcode.MOV: + return False # aside from prologue/epilogue or zeroing EAX, only mov allowed + + # can only mov into return register + src, dst = i.operands[0], i.operands[1] + if dst not in [Register.XMM0, Register.AX]: + return False + + # source must be immediate or RIP-relative + if isinstance(src, Immediate): + return True + + if isinstance(src, Memory) and src.base == Register.IP: + return True + + # source isn't immediate or RIP-relative + return False + + for fn_name, fn_body in parsed_asm.items(): + if fn_name.startswith("target"): + bad_instructions = [i for i in fn_body.instructions if not ok(i)] + self.assertFalse( + bad_instructions, + msg=common.build_msg( + "Found instructions that should have been constant folded", + bad_instructions=bad_instructions, + full_prog=fn_body, + program_path=source_file, + ), + ) + RETVAL_TESTS = { + # Part I "dead_condition.c": 10, "elim_and_copy_prop.c": 10, "remainder_test.c": 1, - "unsigned_compare.c": 1, - "unsigned_wraparound.c": 0, - "const_fold_sign_extend.c": -1000, - "const_fold_sign_extend_2.c": -1000, - "char_round_trip.c": 1, - "signed_unsigned_conversion.c": -11, - "not_char.c": 1, + "listing_19_5.c": 9, + "int_min.c": -2147483648, + # Part II + "listing_19_5_more_types.c": 9, + "integer_promotions.c": 0, } STORE_ELIMINATED = {"alias_analysis_change.c": [5, 10]} +FOLD_CONST_TESTS = { + "fold_cast_to_double.c", + "fold_cast_from_double.c", + "fold_negative_zero.c", + "fold_infinity.c", + "fold_negative_values.c", + "signed_unsigned_conversion.c", + "fold_char_condition.c", + "fold_extension_and_truncation.c", +} def make_whole_pipeline_test(program: Path) -> Callable[[TestWholePipeline], None]: @@ -42,6 +109,11 @@ def test(self: TestWholePipeline) -> None: def test(self: TestWholePipeline) -> None: self.store_eliminated_test(source_file=program, redundant_consts=consts) + elif program.name in FOLD_CONST_TESTS: + + def test(self: TestWholePipeline) -> None: + self.fold_const_test(source_file=program) + else: raise RuntimeError(f"Don't know what to do with {program.name}") diff --git a/test_properties.json b/test_properties.json index 8585cd7e..9f1d027c 100644 --- a/test_properties.json +++ b/test_properties.json @@ -373,7 +373,6 @@ }, "requires_mathlib": [ "chapter_13/valid/function_calls/standard_library_call.c", - "chapter_13/valid/special_values/copysign.c", "chapter_13/valid/libraries/double_params_and_result.c" ], "libs": { diff --git a/tests/chapter_16/valid/chars/access_through_char_pointer.c b/tests/chapter_16/valid/chars/access_through_char_pointer.c index e83eda6d..f4d57d06 100644 --- a/tests/chapter_16/valid/chars/access_through_char_pointer.c +++ b/tests/chapter_16/valid/chars/access_through_char_pointer.c @@ -51,7 +51,4 @@ int main(void) { } return 0; - - - } \ No newline at end of file diff --git a/tests/chapter_19/constant_folding/all_types/fold_cast_from_double.c b/tests/chapter_19/constant_folding/all_types/fold_cast_from_double.c index 22f45e76..2f3403b1 100644 --- a/tests/chapter_19/constant_folding/all_types/fold_cast_from_double.c +++ b/tests/chapter_19/constant_folding/all_types/fold_cast_from_double.c @@ -15,6 +15,7 @@ int target_to_int(void) { } unsigned target_to_uint(void) { + // constant in the range of uint but not int return (unsigned)2147483750.5; } @@ -25,8 +26,8 @@ long target_to_long(void) { } unsigned long target_to_ulong(void) { - // same constant from chapter13/valid/explicit_casts/double_to_ulong.c - return (unsigned long)3458764513821589504.0; + // constant in the range of ulong but not long + return (unsigned long)13835058055282163712.5; } unsigned long target_implicit(void) { @@ -50,7 +51,7 @@ int main(void) { if (target_to_long() != 9223372036854774784l) { return 5; } - if (target_to_ulong() != 3458764513821589504ul) { + if (target_to_ulong() != 13835058055282163712ul) { return 6; } if (target_implicit() != 3458764513821589504ul) { diff --git a/tests/chapter_19/constant_folding/all_types/fold_conditional_jump.c b/tests/chapter_19/constant_folding/all_types/fold_conditional_jump.c new file mode 100644 index 00000000..2ab372fa --- /dev/null +++ b/tests/chapter_19/constant_folding/all_types/fold_conditional_jump.c @@ -0,0 +1,54 @@ +/* Test constant folding of JumpIfZero and JumpIfNotZero instructions + * resulting from && and || operations, with operand types other than int. + * Identical to chapter_19/constant_folding/int_only/fold_conditional_jump.c + * but with non-int operands + * */ +#if defined SUPPRESS_WARNINGS && defined __clang__ +#pragma clang diagnostic ignored "-Wliteral-conversion" +#endif + +// We'll emit two TACKY instructions of the form +// JumpIfZero(0, false_label) +// both should be rewritten as Jump instructions +int target_jz_to_jmp(void) { + return 0l && 0; // 0 +} + +// We'll emit two TACKY instructions of the form +// JumpIfZero(1, false_label) +// both should be removed +int target_remove_jz(void) { + return 1u && 1.; // 1 +} + +// We'll emit two JumpIfNotZero instructions: +// JumpIfNotZero(3, true_label) +// JumpIfNotZero(99, true_label) +// both should be written as Jump instructions +int target_jnz_to_jmp(void) { + return 3.5 || 99ul; // 1 +} + +// We'll emit two JumpIfNotZero instructions: +// JumpIfNotZero(0, true_label) +// JumpIfNotZero(1, true_label) +// we should remove the first, rewrite the second as a Jump instruction +int target_remove_jnz(void) { + return 0ul || 1; // 1 +} + +int main(void) { + if (target_jz_to_jmp() != 0) { + return 1; + } + if (target_remove_jz() != 1) { + return 2; + } + if (target_jnz_to_jmp() != 1) { + return 3; + } + if (target_remove_jnz() != 1) { + return 4; + } + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_19/constant_folding/all_types/fold_double.c b/tests/chapter_19/constant_folding/all_types/fold_double.c index 8a1d1504..b6cb4dbb 100644 --- a/tests/chapter_19/constant_folding/all_types/fold_double.c +++ b/tests/chapter_19/constant_folding/all_types/fold_double.c @@ -10,8 +10,7 @@ #pragma GCC diagnostic ignored "-Woverflow" #endif #endif -// TODO in copy prop section, also include test cases for constant folding w/ -// special values? negative zero, infinity... + double target_add(void) { // Because 1.2345e60 is so large, adding one to it doesn't change its value return 1.2345e60 + 1.; @@ -130,10 +129,10 @@ int main(void) { return 11; } if (target_lt()) { - return 11; + return 12; } if (target_le()) { - return 12; + return 13; } // infinity diff --git a/tests/chapter_19/constant_folding/all_types/negative_zero.c b/tests/chapter_19/constant_folding/all_types/negative_zero.c new file mode 100644 index 00000000..c4ee2699 --- /dev/null +++ b/tests/chapter_19/constant_folding/all_types/negative_zero.c @@ -0,0 +1,19 @@ +/* If we deduplicate floating-point StaticConstant constructs, make sure we + * distinguish between constants with the same value but different alignments. + * Specifically, if we've already added an ordinary constant -0.0, and then we + * need a 16-byte aligned -0.0 to use for negation, don't just reuse the + * previous 8-byte aligned one. (It's okay to either keep them as separate + * constants, or merge them and keep the higher alignment.) This is a regression + * test for a bug in the reference implementation. Note that we can only catch + * this bug once we implement constant folding; before then, we don't add + * positive StaticConstants. + * No 'target' function here because we're just looking for correctness, + * not inspecting assembly. + * */ + +double x = 5.0; + +int main(void) { + double d = -0.0; // add normal constant -0. to list of top-level constants + return (-x > d); // add 16-byte-aligned constant -0. to negate x +} diff --git a/tests/chapter_19/copy_propagation/README.md b/tests/chapter_19/copy_propagation/README.md index b63230f3..0257de8f 100644 --- a/tests/chapter_19/copy_propagation/README.md +++ b/tests/chapter_19/copy_propagation/README.md @@ -4,9 +4,9 @@ In some test programs, the copy propagation and constant folding passes make it In some programs, copy propagation should replace the arguments to certain function calls with constants. In other programs, copy propagation should propagate the same value two different function arguments. The test script validates these programs by checking which values are copied into the parameter-passing registers before the `call` instruction. -Register coalescing, which we implement in Chapter 20, can make it appear that the same value is passed in two different parameter-passing reigsters, even if copy propagation wasn't performed. The tests are designed to prevent register coalescing in those cases, so they'll still test the intended cases after you complete Chapter 20. +Register coalescing, which we implement in Chapter 20, can make it look like the same value is passed in two different parameter-passing registers, even if that value wasn't propagated to both parameters. The tests are designed to prevent register coalescing in those cases, so they'll still test the intended cases after you complete Chapter 20. -In one program (`redundant_copies.c`), removing a redundant copy makes a whole branch dead, allowing unreachable code elimination to remove that branch. The test script validates that this program contains no control-flow instructions. +In a few programs, including `redundant_copies.c`, removing a redundant copy makes a whole branch dead, allowing unreachable code elimination to remove that branch. The test script validates that these programs contains no control-flow instructions. In `pointer_arithmetic.c`, the test script validates that we optimize away all computation instructions (e.g. arithmetic instructions like `imul` and type conversions like `movsx`). diff --git a/tests/chapter_19/copy_propagation/all_types/copy_struct.c b/tests/chapter_19/copy_propagation/all_types/copy_struct.c index b1541f53..fc7cc5dc 100644 --- a/tests/chapter_19/copy_propagation/all_types/copy_struct.c +++ b/tests/chapter_19/copy_propagation/all_types/copy_struct.c @@ -5,7 +5,19 @@ struct s { }; int callee(struct s a, struct s b) { - return a.x == 3 && a.y == 4 && b.x == 3 && b.y == 4; + if (a.x != 3) { + return 1; // fail + } + if (a.y != 4) { + return 2; // fail + } + if (b.x != 3) { + return 3; // fail + } + if (b.y != 4) { + return 4; // fail + } + return 0; // success } int target(void) { diff --git a/tests/chapter_19/copy_propagation/all_types/propagate_into_type_conversions.c b/tests/chapter_19/copy_propagation/all_types/propagate_into_type_conversions.c index a7610c79..d8320253 100644 --- a/tests/chapter_19/copy_propagation/all_types/propagate_into_type_conversions.c +++ b/tests/chapter_19/copy_propagation/all_types/propagate_into_type_conversions.c @@ -12,5 +12,8 @@ int target(void) { } int main(void) { - return target() == 83826; + if (target() != 83826) { + return 1; // fail + } + return 0; // success } \ No newline at end of file diff --git a/tests/chapter_19/copy_propagation/all_types/redundant_double_copies.c b/tests/chapter_19/copy_propagation/all_types/redundant_double_copies.c index 86e086c8..a8c2aaf1 100644 --- a/tests/chapter_19/copy_propagation/all_types/redundant_double_copies.c +++ b/tests/chapter_19/copy_propagation/all_types/redundant_double_copies.c @@ -20,5 +20,8 @@ double target(int flag, int flag2, double y) { } int main(void) { - return target(0, 1, 10.0) == 20.0; + if (target(0, 1, 10.0) != 20.0) { + return 1; // fail + } + return 0; } \ No newline at end of file diff --git a/tests/chapter_19/copy_propagation/int_only/different_source_values_same_copy.c b/tests/chapter_19/copy_propagation/int_only/different_source_values_same_copy.c index 62638cde..9f61bfd8 100644 --- a/tests/chapter_19/copy_propagation/int_only/different_source_values_same_copy.c +++ b/tests/chapter_19/copy_propagation/int_only/different_source_values_same_copy.c @@ -27,11 +27,11 @@ int target(int flag) { int main(void) { int result = target(0); - if (result != 40) + if (result != 200) return 1; result = target(1); - if (result != 20) + if (result != 40) return 2; return 0; // success diff --git a/tests/chapter_19/copy_propagation/int_only/dont_propagate/no_copies_reach_entry.c b/tests/chapter_19/copy_propagation/int_only/dont_propagate/no_copies_reach_entry.c index 7ced5218..852e0d9b 100644 --- a/tests/chapter_19/copy_propagation/int_only/dont_propagate/no_copies_reach_entry.c +++ b/tests/chapter_19/copy_propagation/int_only/dont_propagate/no_copies_reach_entry.c @@ -1,4 +1,4 @@ -/* Make sure we the set of reaching copies from ENTRY is empty */ +/* Make sure we track that the set of reaching copies from ENTRY is empty */ int target(int a, int flag) { if (flag) { // if we initialized ENTRY with the set of all copies in target, diff --git a/tests/chapter_19/dead_store_elimination/README.md b/tests/chapter_19/dead_store_elimination/README.md index 088bf362..c7e85c1e 100644 --- a/tests/chapter_19/dead_store_elimination/README.md +++ b/tests/chapter_19/dead_store_elimination/README.md @@ -1,3 +1,6 @@ To validate that dead stores were eliminated, the test script inspects the assembly for the `target` function. -In most programs, dead store elimination should remove a `Copy` of the form `var = const`, so the test script just validates that that constant doesn't appear in the program. In a couple of cases (`simple.c`, `delete_arithmetic_ops.c` and `self`), dead store elimination combined with other optimizations should eliminate the whole function body except the `Return` instruction; these are validated the same way as the constant-folding tests. The test cases in the `dont_elim` directories cover cases where stores _shouldn't_ be eliminated. The test script doesn't inspect the assembly for these; it just validates that they behave correctly. \ No newline at end of file +In most programs, dead store elimination should remove a `Copy` of the form `var = const`, so the test script just validates that that constant doesn't appear in the program. In a few cases (`simple.c`, `delete_arithmetic_ops.c` and `delete_dead_pt_ii_instructions.c`), dead store elimination combined with other optimizations should eliminate the whole function body except the `Return` instruction. In these cases, the function body should contain only the prologue, a `mov` instruction that moves the expected +constant into EAX, and the epilogue. + +The test cases in the `dont_elim` directories cover cases where stores _shouldn't_ be eliminated. The test script doesn't inspect the assembly for these; it just validates that they behave correctly. \ No newline at end of file diff --git a/tests/chapter_19/dead_store_elimination/all_types/aliased_dead_at_exit.c b/tests/chapter_19/dead_store_elimination/all_types/aliased_dead_at_exit.c index b8c2c19c..ea969278 100644 --- a/tests/chapter_19/dead_store_elimination/all_types/aliased_dead_at_exit.c +++ b/tests/chapter_19/dead_store_elimination/all_types/aliased_dead_at_exit.c @@ -19,5 +19,11 @@ int target(void) { int main(void) { int a = target(); - return a == 100 && b == 10; + if (a != 100) { + return 1; // fail + } + if (b != 10) { + return 2; // fail + } + return 0; // success } \ No newline at end of file diff --git a/tests/chapter_19/dead_store_elimination/all_types/dont_elim/copytooffset_doesnt_kill.c b/tests/chapter_19/dead_store_elimination/all_types/dont_elim/copytooffset_doesnt_kill.c index bf0eb47f..baa854a6 100644 --- a/tests/chapter_19/dead_store_elimination/all_types/dont_elim/copytooffset_doesnt_kill.c +++ b/tests/chapter_19/dead_store_elimination/all_types/dont_elim/copytooffset_doesnt_kill.c @@ -11,5 +11,14 @@ struct s glob = {1, 2, 3}; int main(void) { struct s my_struct = glob; // not a dead store my_struct.c = 100; // this doesn't make my_struct dead - return (my_struct.c == 100 && my_struct.a == 1 && glob.c == 3); + if (my_struct.c != 100 ) { + return 1; // fail + } + if (my_struct.a != 1) { + return 2; // fail + } + if (glob.c != 3) { + return 3; // fail + } + return 0; // success } \ No newline at end of file diff --git a/tests/chapter_19/dead_store_elimination/all_types/dont_elim/recognize_all_uses.c b/tests/chapter_19/dead_store_elimination/all_types/dont_elim/recognize_all_uses.c index b075a36d..d94f64f0 100644 --- a/tests/chapter_19/dead_store_elimination/all_types/dont_elim/recognize_all_uses.c +++ b/tests/chapter_19/dead_store_elimination/all_types/dont_elim/recognize_all_uses.c @@ -144,13 +144,13 @@ int main(void) { return 9; // fail } if (test_double_to_uint(1, 1234567.8) != 1844674407370955264u) { - return 10; + return 10; // fail } if (test_uint_to_double(0, 4294967000U) != 4294967000.) { - return 11; + return 11; // fail } if (test_uint_to_double(1, 4294967000U) != 2147483650u) { - return 12; + return 12; // fail } if (test_truncate(0, 500) != -12) { return 13; // fail diff --git a/tests/chapter_19/unreachable_code_elimination/and_clause.c b/tests/chapter_19/unreachable_code_elimination/and_clause.c new file mode 100644 index 00000000..9322db4d --- /dev/null +++ b/tests/chapter_19/unreachable_code_elimination/and_clause.c @@ -0,0 +1,10 @@ +/* Test that we eliminate the second clause in 0 && y */ +int putchar(int c); + +int target(void) { + return 0 && putchar(97); +} + +int main(void) { + return target(); +} \ No newline at end of file diff --git a/tests/chapter_19/unreachable_code_elimination/dead_after_if_else.c b/tests/chapter_19/unreachable_code_elimination/dead_after_if_else.c index 32bf5a67..3ad5780e 100644 --- a/tests/chapter_19/unreachable_code_elimination/dead_after_if_else.c +++ b/tests/chapter_19/unreachable_code_elimination/dead_after_if_else.c @@ -16,5 +16,11 @@ int target(int a) { return callee(); // this should be optimized away } int main(void) { - return (target(1) == 1 && target(0) == 2); + if (target(1) != 1) { + return 1; // fail + } + if (target(0) != 2) { + return 2; // fail + } + return 0; // success } \ No newline at end of file diff --git a/tests/chapter_19/unreachable_code_elimination/dead_branch_inside_loop.c b/tests/chapter_19/unreachable_code_elimination/dead_branch_inside_loop.c index 55de1649..ce551786 100644 --- a/tests/chapter_19/unreachable_code_elimination/dead_branch_inside_loop.c +++ b/tests/chapter_19/unreachable_code_elimination/dead_branch_inside_loop.c @@ -23,5 +23,8 @@ int target(void) { } int main(void) { - return target(); + if (target() != -4845) { + return 1; // fail + } + return 0; // success } \ No newline at end of file diff --git a/tests/chapter_19/unreachable_code_elimination/empty_block.c b/tests/chapter_19/unreachable_code_elimination/empty_block.c index 263cffc4..3ed8681a 100644 --- a/tests/chapter_19/unreachable_code_elimination/empty_block.c +++ b/tests/chapter_19/unreachable_code_elimination/empty_block.c @@ -12,5 +12,11 @@ int target(int x, int y) { } int main(void) { - return target(1, 1) == 1 && target(0, 0) == 1; + if (target(1, 1) != 1) { + return 1; // fail + } + if (target(0,0) != 1) { + return 2; // fail + } + return 0; // success } \ No newline at end of file diff --git a/tests/chapter_19/unreachable_code_elimination/or_clause.c b/tests/chapter_19/unreachable_code_elimination/or_clause.c new file mode 100644 index 00000000..b1061173 --- /dev/null +++ b/tests/chapter_19/unreachable_code_elimination/or_clause.c @@ -0,0 +1,10 @@ +/* Test that we eliminate the second clause in 1 || x */ +int putchar(int c); + +int target(void) { + return 1 || putchar(97); +} + +int main(void) { + return target(); +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/README.md b/tests/chapter_19/whole_pipeline/README.md new file mode 100644 index 00000000..53a42901 --- /dev/null +++ b/tests/chapter_19/whole_pipeline/README.md @@ -0,0 +1,3 @@ +To validate that all optimization passes were run until the results converge, the test script inspects the assembly for any functions starting with `target`. + +In one test program (`alias_analysis_change.c`) we make sure that stores of specific constants were removed, just like we do for some dead store elimination tests. In the remaining test programs, we validate that each target function is optimized down to a single `Return` instruction, much like we do for other dead store elimination tests. Many of the tests in this chapter focus on validating constant-folding logic that we couldn't validate before we'd implemented copy propagation (like constant folding with chararacter types and negative numbers). \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/alias_analysis_change.c b/tests/chapter_19/whole_pipeline/all_types/alias_analysis_change.c index 193428be..8a36032b 100644 --- a/tests/chapter_19/whole_pipeline/all_types/alias_analysis_change.c +++ b/tests/chapter_19/whole_pipeline/all_types/alias_analysis_change.c @@ -1,22 +1,27 @@ -#if defined SUPPRESS_WARNINGS -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif +/* Test that we rerun alias analysis with each pipeline iteration */ + +int putchar(int c); int foo(int *ptr) { - return 2; + putchar(*ptr); + return 0; } int target(void) { - int x = 10; - int *ptr = 0; + int x = 10; // this is a dead store + int y = 65; + int *ptr = &y; if (0) { - // need to update alias after dead code elim to recognize that - // x is not actually aliased + // on our first pass through the pipeline it will look like x is + // aliased; on later passes, after unreachable code elimination removes + // this branch, we'll recognize that x is not aliased ptr = &x; } - x = 5; // this is a dead store - foo(ptr); // TODO could also validate that 0 is propagated to here as a - // function argument + x = 5; // this is a dead store, but we'll only recognize this after + // rerunning alias analysis + foo(ptr); // we'll think this makes x live until we recognize that x is not + // aliased + return 0; } diff --git a/tests/chapter_19/whole_pipeline/all_types/char_round_trip.c b/tests/chapter_19/whole_pipeline/all_types/char_round_trip.c deleted file mode 100644 index 0548def7..00000000 --- a/tests/chapter_19/whole_pipeline/all_types/char_round_trip.c +++ /dev/null @@ -1,13 +0,0 @@ -// test constant folding of type conversions between char and int; -// this may already be covered elsewhere -int target(void) { - int i = 257; - char c = i; - i = 255; - char c2 = i; - return (int)c == 1 && (int) c2 == -1; -} - -int main(void) { - return target(); -} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/const_fold_sign_extend.c b/tests/chapter_19/whole_pipeline/all_types/const_fold_sign_extend.c deleted file mode 100644 index 382db8f6..00000000 --- a/tests/chapter_19/whole_pipeline/all_types/const_fold_sign_extend.c +++ /dev/null @@ -1,7 +0,0 @@ -long target(void) { - return -1000; -} - -int main(void) { - return target() == -1000l; -} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/const_fold_sign_extend_2.c b/tests/chapter_19/whole_pipeline/all_types/const_fold_sign_extend_2.c deleted file mode 100644 index 07ccc13f..00000000 --- a/tests/chapter_19/whole_pipeline/all_types/const_fold_sign_extend_2.c +++ /dev/null @@ -1,7 +0,0 @@ -unsigned long target(void) { - return -1000; -} - -int main(void) { - return target() == 18446744073709550616ul; -} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/fold_cast_from_double.c b/tests/chapter_19/whole_pipeline/all_types/fold_cast_from_double.c new file mode 100644 index 00000000..70408df7 --- /dev/null +++ b/tests/chapter_19/whole_pipeline/all_types/fold_cast_from_double.c @@ -0,0 +1,31 @@ +/* Constant-folding tests for conversions from negative doubles to integer + * types; couldn't test these before because we need copy prop to fully evaluate + * them. + * */ + +char target_to_char(void) { + return (char)-126.5; +} + +int target_to_int(void) { + return (int)-5.9; +} + +long target_to_long(void) { + // nearest representable double is -9223372036854774784.0, + // which will be converted to long int -9223372036854774784 + return (long)-9223372036854774783.1; +} + +int main(void) { + if (target_to_char() != -126) { + return 1; + } + if (target_to_int() != -5) { + return 2; + } + if (target_to_long() != -9223372036854774784l) { + return 3; + } + return 0; +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/fold_cast_to_double.c b/tests/chapter_19/whole_pipeline/all_types/fold_cast_to_double.c new file mode 100644 index 00000000..242bbb0a --- /dev/null +++ b/tests/chapter_19/whole_pipeline/all_types/fold_cast_to_double.c @@ -0,0 +1,92 @@ +/* Constant-folding tests for conversions to double from chars and negative + * ints; couldn't test these before because we need copy prop to fully evaluate + * them. + * */ + +#ifdef SUPPRESS_WARNINGS +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wconstant-conversion" +#else +#pragma GCC diagnostic ignored "-Woverflow" +#endif +#endif + +double copysign(double x, double y); // standard math library + +double target_from_neg_int(void) { + return (double)-2147483647; // can convert exactly +} + +// exactly between two representable doubles; +// same as target_from_long in constant_folding/all_types/fold_cast_to_double.c +// but negated +double target_from_neg_long(void) { + return (double)-4611686018427388416l; +} + +// test conversion from char to double +double target_from_char(void) { + char c = 127; + return (double)c; +} + +// test conversion from signed char to double +double target_from_schar(void) { + char c = -127; + return (double)c; +} + +// test conversion from uchar to double +double target_from_uchar(void) { + unsigned char u = 255; + return (double)u; +} + +// if we initially assign char a value outside its range, +// make sure we truncate before converting to double +double target_from_truncated_char(void) { + char c = -129; + return (double)c; // 127 +} + +// if we initially assign uchar a value outside its range, +// make sure we truncate before converting to double +double target_from_truncated_uchar(void) { + unsigned char c = 1000; + return (double)c; // 232 +} + +double target_from_negated_int_zero(void) { + // negating integer zero is just zero, + // which will be converted to positive floating-point zero + return -0; +} + +int main(void) { + if (target_from_neg_int() != -2147483647.) { + return 1; + } + if (target_from_neg_long() != -4611686018427387904.0) { + return 2; + } + if (target_from_char() != 127) { + return 3; + } + if (target_from_schar() != -127) { + return 4; + } + if (target_from_uchar() != 255) { + return 5; + } + if (target_from_truncated_char() != 127) { + return 6; + } + if (target_from_truncated_uchar() != 232) { + return 7; + } + double zero = target_from_negated_int_zero(); + if (zero != 0 || copysign(5., zero) != 5.) { + return 8; + } + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/fold_char_condition.c b/tests/chapter_19/whole_pipeline/all_types/fold_char_condition.c new file mode 100644 index 00000000..d9283d5f --- /dev/null +++ b/tests/chapter_19/whole_pipeline/all_types/fold_char_condition.c @@ -0,0 +1,85 @@ +/* Test constant folding of Not, JumpIfZero, and JumpIfNotZero with char + * operands. (We don't test constant-folding of other operations on char because + * they get promoted to int first.) + * */ +#ifdef SUPPRESS_WARNINGS +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wconstant-conversion" +#else +#pragma GCC diagnostic ignored "-Woverflow" +#endif +#endif +int putchar(int c); + +int target_not_char(void) { + char x = 256; // 0 + return !x; // 1 +} + +int target_not_uchar(void) { + unsigned char x = 256; // 0 + return !x; // 1 +} + +int target_not_true_char(void) { + char x = -1; + return !x; // 0; +} + +int target_and_schar(void) { + signed char c = 0; + return c && putchar('a'); // return 1, eliminate call to putchar +} + +int target_and_true_char(void) { + signed char c1 = 44; + char c2 = c1 - 10; + return c1 && c2; // 1 +} + +int target_or_uchar(void) { + unsigned char u = 250; + return u || putchar('a'); // return 1, eliminate call to putchar +} + +int target_or_char(void) { + char c = 250; + return c || putchar('a'); // return 1, eliminate call to putchar +} + +char target_branch_char(void) { + unsigned char u = 250; + u = u + 6; // 0 + if (u) { // eliminate this branch + putchar('a'); + } + return u + 10; +} + +int main(void) { + if (target_not_char() != 1) { + return 1; // fail + } + if (target_not_uchar() != 1) { + return 2; // fail + } + if (target_not_true_char() != 0) { + return 3; // fail + } + if (target_and_schar() != 0) { + return 4; // fail + } + if (target_and_true_char() != 1) { + return 5; // fail + } + if (target_or_uchar() != 1) { + return 6; // fail + } + if (target_or_char() != 1) { + return 7; // fail + } + if (target_branch_char() != 10) { + return 8; // fail + } + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/fold_extension_and_truncation.c b/tests/chapter_19/whole_pipeline/all_types/fold_extension_and_truncation.c new file mode 100644 index 00000000..50f595be --- /dev/null +++ b/tests/chapter_19/whole_pipeline/all_types/fold_extension_and_truncation.c @@ -0,0 +1,335 @@ +/* Test constant folding of sign extension, zero extension, and truncation. + * We couldn't test this thoroughly during the constant folding phase because + * we hadn't implemented copy propagation yet. + * */ + +#ifdef SUPPRESS_WARNINGS +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wconstant-conversion" +#else +#pragma GCC diagnostic ignored "-Woverflow" +#endif +#endif + +/* Sign extension */ + +// Test sign-extension from int to long +// Make sure we propagate converted value, rather than +// original value, into later expression +long target_extend_int_to_long(void) { + int i = -1000; + long l = (long)i; + return (l - 72057594037927936l) / 3l; // result is outside the range of int +} + +// Test sign-extension from int to ulong +// same idea as above +unsigned long target_extend_int_to_ulong(void) { + int i = -1000; + unsigned long u = (unsigned long)i; + return u % 50ul; +} + +/* Zero extension */ +long target_extend_uint_to_long(void) { + unsigned int u = 2147483648u; // 2^31 + long l = (long)u; + // make sure it's positive + if (l < 0) { + return 0; // fail + } + return l % 7l; +} + +unsigned long target_extend_uint_to_ulong(void) { + unsigned int u = 4294967295U; + unsigned long l = (unsigned long)u; + return (l == 4294967295Ul); +} + +/* Truncation */ + +// Test truncation from long to int +// make sure we're actually performing truncation (as opposed to, +// say, just storing ints as 64-bit values internally, then making truncation a +// no-op or zeroing out upper bytes regardless of sign) +int target_truncate_long_to_int(void) { + long l = 9223372036854775807l; // LONG_MAX + int i = (int)l; // -1 + long l2 = -9223372036854775807l - 1l; // LONG_MIN + int i2 = (int)l2; // 0 + // make sure we propagate truncated value (0) and not original value + // (nonzero) + if (i2) { // eliminate this + return 0; + } + // make sure we propagate truncated value + // if we use original value, result of division will be different + // even if you only look at lower 32 bits + return 20 / i; +} + +// Test truncation from long to int +// same idea as above +unsigned int target_truncate_long_to_uint(void) { + long l = -9223372032559808513l; // LONG_MIN + UINT_MAX + unsigned int u = (unsigned)l; // UINT_MAX + if (u - 4294967295U) { // eliminate this + return 0; + } + return u / 20; +} + +// Test truncation from unsigned long to int +int target_truncate_ulong_to_int(void) { + unsigned long ul = 18446744073709551615UL; // ULONG_MAX + int i = (int)ul; // -1 + unsigned long ul2 = 9223372039002259456ul; // 2^63 + 2^31 + int i2 = (int)ul2; // INT_MIN + if (i2 >= 0) { // eliminate this + return 0; + } + return 10 / i; // -10 +} + +// Test truncation from unsigned long to unsigned int +unsigned int target_truncate_ulong_to_uint(void) { + unsigned long ul = 18446744073709551615UL; // ULONG_MAX + unsigned int u = (unsigned int)ul; // UINT_MAX + return u / 20; +} + +/* Conversions to/from character types. + * There are no constants of character type, and chars are promoted + * to int before almost every operation, so we can't test truncation and + * extension separately + * */ + +// Test truncation from int to char/signed char, and sign-extension +// from char/signed char to int +// make sure we're actually performing truncation/extension (as opposed to, +// say, just treating chars as 32-bit ints and making extension/truncation a +// no-op) +int target_char_int_conversion(void) { + // convert a wide range of ints to chars + int i = 257; + char c = i; + i = 255; + char c2 = i; + i = 2147483647; // INT_MAX + signed char c3 = i; + i = -2147483647 - 1; // INT_MIN + char c4 = i; + i = -129; // all bits set except bit 128 - need to zero out all upper bits + // when we convert this back to int + signed char c5 = i; + i = 128; // only bit 128 is set - need to sign-extend to all upper bites + // when we convert this back to int + char c6 = i; + // we'll convert these chars back to ints implicitly + // as part of usual arithmetic conversions + // for != + if (c != 1) { + return 1; // fail + } + if (c2 != -1) { + return 2; // fail + } + if (c3 != -1) { + return 3; // fail + } + if (c4 != 0) { + return 4; // fail + } + if (c5 != 127) { + return 5; // fail + } + if (c6 != -128) { + return 6; // fail + } + return 0; // success +} + +int target_uchar_int_conversion(void) { + int i = 767; + unsigned char uc1 = i; // 255 + i = 512; + unsigned char uc2 = i; // 0 + i = -2147483647; // INT_MIN + 1 + unsigned char uc3 = i; // 1 + i = -2147483647 + 127; // INT_MIN + 128 + unsigned char uc4 = i; // 128 + + // we'll implicitly zero-extend these unsigned chars back to ints + // for comparisons + if (uc1 != 255) { + return 1; // fail + } + if (uc2) { + return 2; // fail + } + if (uc3 != 1) { + return 3; // fail + } + if (uc4 != 128) { + return 1; // fail + } + return 0; // success +} + +int target_char_uint_conversion(void) { + char c = 2148532223u; // 2^30 + 2^20 - 1, truncates to -1 + signed char c2 = 2147483775u; // 2^31 + 127, truncates to 127 + unsigned int u = (unsigned int)c; // UINT_MAX + if (u != 4294967295U) { + return 1; // fail + } + u = (unsigned int)c2; + if (u != 127u) { + return 2; // fail + } + return 0; +} + +int target_uchar_uint_conversion(void) { + unsigned char uc = 2148532223u; // 2^30 + 2^20 - 1, truncates to 255 + unsigned int ui = (unsigned int)uc; + if (ui != 255u) { + return 1; // fail + } + return 0; +} + +int target_char_long_conversion(void) { + long l = 3377699720528001l; // 2^51 + 2^50 + 129 + char c = l; // truncates to -127 + l = 9223372036854775807l; // LONG_MAX + char c2 = l; // -1 + l = 2147483648l + 127l; // 2^32 + 127 + signed char c3 = l; // 127 + l = -2147483647l - 1l; // INT_MIN (as a long) + char c4 = l; // 0 + l = 2147483648l + 128l; + signed char c5 = l; // -128 + // we'll convert these chars back to ints implicitly + // as part of usual arithmetic conversions + // for != + if (c != -127l) { + return 1; // fail + } + if (c2 != -1l) { + return 2; // fail + } + if (c3 != 127l) { + return 3; // fail + } + if (c4) { + return 4; // fail + } + if (c5 != -128l) { + return 5; // fail + } + return 0; // success +} + +int target_uchar_long_conversion(void) { + long l = 255l + 4294967296l; + unsigned char uc1 = l; // 255 + l = 36028798092705792l; // 2^55 + 2^30 + unsigned char uc2 = l; // 0 + l = -9223372036854775807l; // LONG_MIN + 1 + unsigned char uc3 = l; // 1 + l = -9223372036854775807l + 127; // LONG_MIN + 128 + unsigned char uc4 = l; // 128 + + // we'll implicitly zero-extend these unsigned chars back to ints + // for comparisons + if (uc1 != 255) { + return 1; // fail + } + if (uc2) { + return 2; // fail + } + if (uc3 != 1) { + return 3; // fail + } + if (uc4 != 128) { + return 1; // fail + } + return 0; // success +} + +int target_char_ulong_conversion(void) { + char c = 9223373136366403583ul; // 2^63 + 2^40 - 1, truncates to -1 + signed char c2 = 9223372036854775935ul; // 2^63 + 127, truncates to 127 + unsigned long ul = (unsigned long)c; // ULONG_MAX + if (ul != 18446744073709551615UL) { + return 1; // fail + } + ul = (unsigned long)c2; + if (ul != 127ul) { + return 2; // fail + } + return 0; +} + +int target_uchar_ulong_conversion(void) { + unsigned char uc = + 9223372037929566207ul; // 2^63 + 2^30 + 2^20 - 1, truncates to 255 + unsigned int ui = (unsigned int)uc; + if (ui != 255u) { + return 1; // fail + } + return 0; +} +int main(void) { + if (target_extend_int_to_long() != -24019198012642978l) { + return 1; // fail + } + if (target_extend_int_to_ulong() != 16ul) { + return 2; // fail + } + if (target_extend_uint_to_long() != 2l) { + return 3; // fail + } + if (target_extend_uint_to_ulong() != 1ul) { + return 4; // fail + } + if (target_truncate_long_to_int() != -20) { + return 5; // fail + } + if (target_truncate_long_to_uint() != 214748364u) { + return 6; // fail + } + if (target_truncate_ulong_to_int() != -10) { + return 7; // fail + } + if (target_truncate_ulong_to_uint() != 214748364u) { + return 8; // fail + } + if (target_char_int_conversion()) { + return 9; // fail + } + if (target_uchar_int_conversion()) { + return 10; // fail + } + if (target_char_uint_conversion()) { + return 11; // fail + } + if (target_uchar_uint_conversion()) { + return 12; // fail + } + if (target_char_long_conversion()) { + return 13; // fail + } + if (target_uchar_long_conversion()) { + return 14; // fail + } + if (target_char_ulong_conversion()) { + return 15; // fail + } + if (target_uchar_ulong_conversion()) { + return 16; // fail + } + return 0; +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/fold_infinity.c b/tests/chapter_19/whole_pipeline/all_types/fold_infinity.c new file mode 100644 index 00000000..2799a697 --- /dev/null +++ b/tests/chapter_19/whole_pipeline/all_types/fold_infinity.c @@ -0,0 +1,202 @@ +/* Test constant folding with infinity. + * We couldn't test this in the constant folding stage because it requires + * copy propagation. + * */ + +#ifdef SUPPRESS_WARNINGS +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wliteral-range" +#else +#pragma GCC diagnostic ignored "-Woverflow" +#endif +#endif + +double copysign(double x, double y); // from standard library + +// helper functions +int is_positive_zero(double d) { + if (d != 0.0) { + // it's non-zero + return 0; + } + // make sure the sign is positive + return (copysign(5., d) == 5.0); +} + +int is_negative_zero(double d) { + if (d != 0.0) { + // it's non-zero + return 0; + } + // make sure the sign is negative + return (copysign(5., d) == -5.); +} + +int target_infinity_equal(void) { + // 1.0 / 0.0 evaluates to infinity + // 11e330 rounds to infinity + // infinity compares equal to itself + return 1.0 / 0.0 == 11e330; +} + +int target_infinity_gt(void) { + // 1.0 / 0.0 evaluates to infinity + // infinity compares greater than all finite value + return 1.0 / 0.0 > 1.79E308; +} + +int target_neg_infinity_lt(void) { + // -1.0 / 0.0 evaluates to negative infinity + // which compares less than all finite values + return -1.0 / 0.0 < -1.79E308; +} + +// adding any finite number to infinity results in infinity +double target_add_infinity(void) { + return (1.0 / 0.0) + 1000e10; +} + +// subtracting a finite number from infinity results in infinity +double target_sub_infinity(void) { + return (1.0 / 0.0) - 1000e10; +} + +// any finite number times infinity is positive or negative infinity +// with the sign following the usual rules for multiplication +double target_mult_infinity(void) { + return (1.0 / 0.0) * 25.; // infinity +} + +double target_mult_neg_infinity(void) { + return (-1.0 / 0.0) * 25.; // negative infinity +} + +double target_mult_neg_infinity_by_neg_number(void) { + return (-1.0 / 0.0) * -25.; // positive infinity +} + +// infinity divided by any finite number is infinity +// with the sign following the usual rules for divison +double target_div_infinity_by_num(void) { + return (1. / 0.) / 5.; +} + +// negating infinity produces negative infinity +double target_negate_inf(void) { + double infin = 1.0 / 0.0; + return -infin; +} + +// if the true result of an operation is bigger than the largest representable +// double, it results in infinity +// note that these tests call this "overflow" but technically it's not - it's +// well-defined +double target_mult_overflow(void) { + return 2e300 * 10e20; // infinity +} + +double target_div_overflow(void) { + return 1e308 / -10e-20; // negative infinity +} + +double target_add_overflow(void) { + return 1.79e308 + 1e308; // infinity +} + +double target_sub_overflow(void) { + return -1e308 - 1e308; // negative infinity +} + +// 0 divided by infinity is zero +// signs follow the usual rules for division +double target_zero_div_by_inf(void) { + return 0. / (3.0 / 0.); // zero +} + +double target_zero_div_by_neg_inf(void) { + return 0. / (3.0 / -0.); // negative zero +} + +double target_negative_zero_div_by_inf(void) { + return -0. / (0.005 / 0.); // negative zero +} + +// infinity evaluates to true in conditional +int target_infinity_is_true(void) { + double infin = 2345.0 / 0.0; + if (infin) { + return 1; // success + } + return 0; // failure +} + +double zero = 0.; + +int main(void) { + // calculate infinity here with an expression we can't constant fold, + // so the value we validate against is right even if constant folding is + // incorrect + double infinity = 1. / zero; + + if (!target_infinity_equal()) { + return 1; // fail + } + if (!target_infinity_gt()) { + return 2; // fail + } + if (!target_neg_infinity_lt()) { + return 3; // fail + } + + if (target_add_infinity() != infinity) { + return 4; // fail + } + + if (target_sub_infinity() != infinity) { + return 5; // fail + } + if (target_mult_infinity() != infinity) { + return 6; // fail + } + + if (target_mult_neg_infinity() != -infinity) { + return 7; // fail + } + if (target_mult_neg_infinity_by_neg_number() != infinity) { + return 8; // fail + } + if (target_div_infinity_by_num() != infinity) { + return 9; // fail + } + if (target_negate_inf() != -infinity) { + return 10; // fail + } + if (target_mult_overflow() != infinity) { + return 11; // fail + } + if (target_div_overflow() != -infinity) { + return 12; // fail + } + if (target_add_overflow() != infinity) { + return 13; // fail + } + if (target_sub_overflow() != -infinity) { + return 14; // fail + } + double d = target_zero_div_by_inf(); + if (!is_positive_zero(d)) { + return 15; // fail + } + d = target_zero_div_by_neg_inf(); + if (!is_negative_zero(d)) { + return 16; // fail + } + d = target_negative_zero_div_by_inf(); + if (!is_negative_zero(d)) { + return 17; // fail + } + if (target_infinity_is_true() != 1) { + return 18; // fail + } + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/fold_negative_values.c b/tests/chapter_19/whole_pipeline/all_types/fold_negative_values.c new file mode 100644 index 00000000..6ca70af9 --- /dev/null +++ b/tests/chapter_19/whole_pipeline/all_types/fold_negative_values.c @@ -0,0 +1,81 @@ +/* Test constant folding with negative numbers (including double and long); + * we couldn't test this in the constant-folding stage because it requires + * copy propagation. + * */ + +/* long tests */ + +/* similar to int-only remainder_test but with long instead of int */ +long target_remainder_test(void) { + // same expression as in chapter_11/valid/long_expressions/arithmetic_ops.c + // but constant-foldable + return -8589934585l % 4294967290l; +} + +long target_long_subtraction(void) { + // same expression as in chapter_11/valid/long_expressions/arithmetic_ops.c + // but constant-foldable + return -4294967290l - 90l; +} + +long target_long_division(void) { + // same expression as in chapter_11/valid/long_expressions/arithmetic_ops.c + // but constant-foldable and w/ first operand negated + return (-4294967290l / 128l); +} + +long target_long_complement(void) { + return ~-9223372036854775807l; +} + +/* double tests */ +double target_double_add(void) { + // Because the magnitude of -1.2345e60 is so large, + // adding one to it doesn't change its value + // (same as target_add in + // tests/chapter_19/constant_folding/all_types/fold_double.c with one + // operand negated) + return -1.2345e60 + 1.; +} + +double target_double_sub(void) { + // calculate the difference between two very close + // subnormal numbers (same as target_sub in + // tests/chapter_19/constant_folding/all_types/fold_double.c + // with operands negated) + return -5.85543871245623688067e-311 - -5.85543871245574281503e-311; +} + +double target_double_div(void) { + // same as target_div in + // tests/chapter_19/constant_folding/all_types/fold_double.c + // with one operand negated + return -1100.5 / 5000.; +} + +int main(void) { + // long tests + if (target_remainder_test() != -5l) { + return 1; // fail + } + if (target_long_subtraction() != -4294967380l) { + return 2; // fail + } + if (target_long_division() != -33554431l) { + return 3; // fail + } + if (target_long_complement() != 9223372036854775806l) { + return 4; // fail + } + // double tests + if (target_double_add() != -1.2345e60) { + return 5; // fail + } + if (target_double_sub() != -5e-324) { + return 6; // fail + } + if (target_double_div() != -0.2201) { + return 7; // fail + } + return 0; +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/fold_negative_zero.c b/tests/chapter_19/whole_pipeline/all_types/fold_negative_zero.c new file mode 100644 index 00000000..c8468a34 --- /dev/null +++ b/tests/chapter_19/whole_pipeline/all_types/fold_negative_zero.c @@ -0,0 +1,309 @@ +/* Test constant folding with negative zero. + * We couldn't test this in the constant folding stage because it requires + * copy propagation. + * See https://en.wikipedia.org/wiki/Signed_zero#Properties_and_handling for + * a quick reference on arithmetic operations with -0.0 + * */ + +#ifdef SUPPRESS_WARNINGS +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wliteral-conversion" +#endif +#endif + +double copysign(double x, double y); // from standard library + +// helper functions +int is_positive_zero(double d) { + if (d != 0.0) { + // it's non-zero + return 0; + } + // make sure the sign is positive + return (copysign(5., d) == 5.0); +} + +int is_negative_zero(double d) { + if (d != 0.0) { + // it's non-zero + return 0; + } + // make sure the sign is negative + return (copysign(5., d) == -5.); +} + +/* Comparisons */ + +// 0.0 and -0.0 should compare equal +int target_negative_zero_eq(void) { + return 0.0 == -0.0; // true +} + +int target_negative_zero_neq(void) { + return 0.0 != -0.0; // false +} + +int target_negative_zero_lt(void) { + return -0.0 < 0.0; // false - they're equal, so -0. is not less than 0. +} + +int target_negative_zero_gt(void) { + return -0.0 > 0.0; // false - they're equal, so 0. is not greater than 0. +} + +int target_negative_zero_ge(void) { + return -0.0 >= 0.0; // true b/c operands are equal +} + +int target_negative_zero_le(void) { + return -0.0 <= 0.0; // true b/c operands are equal +} + +// make sure -0.0 counts as 0 in conditionals/booleans +int target_neg_zero_branch(void) { + if (-0.0) { + return 1; + } + return 0; +} + +int target_not_neg_zero(void) { + return !-0.0; // 1 +} + +int target_neg_zero_and(void) { + return -0.0 && 1; +} + +/* Addition */ +double target_add_negative_zero_to_self(void) { + return -0. + -0.; // negative (special case) +} + +double target_add_positive_to_negative_zero(void) { + // posiive (-0.0 + 0.0 ==> 0.0 -- 0.0, and x - x is always +0.0) + return -0. + 0.; +} + +double target_add_negative_to_positive_zero(void) { + return 0. + -0.; // positive; equivalent to previous case +} + +double target_add_negative_nonzero_to_negative_zero(void) { + // adding any number to negative zero results in the same number + return -5.0 + -0.; +} + +double target_add_positive_nonzero_to_negative_zero(void) { + // adding any number to negative zero results in the same number + return -0. + 10.; +} + +/* Subtraction */ +double target_subtract_neg_zero_from_self(void) { + return -0. - -0.; // positive zero; equivalent to 0. - 0. +} + +double target_subtract_pos_zero_from_neg_zero(void) { + return -0. - 0.; // negative zero; equivalent to -0. + -0. +} + +double target_subtract_neg_zero_from_pos_zero(void) { + return 0. - -0.; // positive zero; equivalent to 0. + 0. +} + +double target_subtract_pos_nonzero_from_neg_zero(void) { + return -0. - 10.; // -10. +} + +/* Multiplication */ +double target_negative_zero_mult(void) { + return -0.0 * 15.4e10; // negative zero +} + +double target_negative_zero_mult_negative(void) { + return -100. * -0.; // positive zero +} + +double target_negative_zero_squared(void) { + return -0. * -0.; // positive zero +} + +double target_neg_zero_mult_zero(void) { + return 0. * -0.; // negative zero +} + +double target_mult_underflow(void) { + return -5.85543871245623688067e-320 * + 0.5e-5; // underflows to negative zero +} + +/* division */ + +double target_div_neg_zero_by_pos_nonzero(void) { + return -0. / 10.; // negative zero +} + +double target_div_pos_zero_by_neg_nonzero(void) { + return 0. / -10.; // negative zero +} + +double target_div_neg_zero_by_neg_nonzero(void) { + return -0. / -5.; // positive zero +} + +double target_div_negative_underflow(void) { + // this result should underflow to negative zero + return 0.5e-100 / -2e307; +} + +double target_div_pos_non_zero_by_neg_zero(void) { + return 10. / -0.0; // negative infinity +} + +double target_div_neg_nonzero_by_zero(void) { + return -10. / 0.; // negative infinity +} + +double target_div_neg_nonzero_by_neg_zero(void) { + return -100. / -0.; // positive infinity +} + +/* negation */ +double target_negate_neg_zero(void) { + return -(-0.0); // positive zero +} + +// we can calculate zero and negate it (i.e. we're not just treating the +// source-level expression -0.0 as a special case) +double target_negate_calculated_zero(void) { + return -(50. - 50.); +} + +int main(void) { + if (target_negative_zero_eq() != 1) { + return 1; // fail + } + if (target_negative_zero_neq() != 0) { + return 2; // fail + } + if (target_negative_zero_lt() != 0) { + return 3; // fail + } + if (target_negative_zero_gt() != 0) { + return 4; // fail + } + if (target_negative_zero_ge() != 1) { + return 5; // fail + } + if (target_negative_zero_le() != 1) { + return 6; // fail + } + if (target_neg_zero_branch()) { + return 7; // fail + } + if (target_not_neg_zero() != 1) { + return 8; // fail + } + if (target_neg_zero_and() != 0) { + return 9; // fail + } + + double d; + d = target_add_negative_zero_to_self(); + if (!is_negative_zero(d)) { + return 10; // fail + } + d = target_add_positive_to_negative_zero(); + if (!is_positive_zero(d)) { + return 11; // fail + } + d = target_add_negative_to_positive_zero(); + if (!is_positive_zero(d)) { + return 12; // fail + } + d = target_add_negative_nonzero_to_negative_zero(); + if (d != -5.) { + return 13; // fail + } + d = target_add_positive_nonzero_to_negative_zero(); + if (d != 10.) { + return 14; // fail + } + + d = target_subtract_neg_zero_from_self(); + if (!is_positive_zero(d)) { + return 15; // fail + } + d = target_subtract_pos_zero_from_neg_zero(); + if (!is_negative_zero(d)) { + return 16; // fail + } + d = target_subtract_neg_zero_from_pos_zero(); + if (!is_positive_zero(d)) { + return 17; // fail + } + d = target_subtract_pos_nonzero_from_neg_zero(); + if (d != -10.) { + return 18; // fail + } + + d = target_negative_zero_mult(); + if (!is_negative_zero(d)) { + return 19; // fail + } + d = target_negative_zero_mult_negative(); + if (!is_positive_zero(d)) { + return 20; // fail + } + d = target_negative_zero_squared(); + if (!is_positive_zero(d)) { + return 21; // fail + } + d = target_neg_zero_mult_zero(); + if (!is_negative_zero(d)) { + return 22; // fail + } + d = target_mult_underflow(); + if (!is_negative_zero(d)) { + return 23; // fail + } + + d = target_div_neg_zero_by_pos_nonzero(); + if (!is_negative_zero(d)) { + return 24; // fail + } + d = target_div_pos_zero_by_neg_nonzero(); + if (!is_negative_zero(d)) { + return 25; // fail + } + d = target_div_neg_zero_by_neg_nonzero(); + if (!is_positive_zero(d)) { + return 26; // fail + } + d = target_div_pos_non_zero_by_neg_zero(); + if (d >= -1.79e308) { // should be negative infinity + return 27; // fail + } + d = target_div_neg_nonzero_by_zero(); + if (d >= -1.79e308) { // should be negative infinity + return 28; // fail + } + d = target_div_neg_nonzero_by_neg_zero(); + if (d <= 1.79e308) { // should be infinity + return 29; // fail + } + d = target_div_negative_underflow(); + if (!is_negative_zero(d)) { + return 30; + } + d = target_negate_neg_zero(); + if (!is_positive_zero(d)) { + return 31; // fail + } + d = target_negate_calculated_zero(); + if (!is_negative_zero(d)) { + return 32; // fail + } + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/integer_promotions.c b/tests/chapter_19/whole_pipeline/all_types/integer_promotions.c new file mode 100644 index 00000000..003288dd --- /dev/null +++ b/tests/chapter_19/whole_pipeline/all_types/integer_promotions.c @@ -0,0 +1,27 @@ +/* Make sure we promote characters to integers before constant folding */ + +int target(void) { + char c1 = 120; + char c2 = 3; + // if this weren't promoted, c1 + c1 would overflow, causing undefined behavior + // if we had c1 + c1 wrap around to -16, this would result in -5 + // but because we promote results to ints, this is 240 / 3, or 80 + char c3 = (c1 + c1) / c2; + + unsigned char uc1 = 200; + unsigned char uc2 = 12; + // if we didn't perform integer promotions, uc1 + uc1 would wrap around + // to 144 and the result would be 12. With promotions, this is 400/12, or 33. + unsigned char uc3 = (uc1 + uc1) / uc2; + if (c3 != 80) { + return 1; // fail + } + if (uc3 != 33) { + return 2; // fail + } + return 0; +} + +int main(void) { + return target(); +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/listing_19_5_more_types.c b/tests/chapter_19/whole_pipeline/all_types/listing_19_5_more_types.c new file mode 100644 index 00000000..01fb3c38 --- /dev/null +++ b/tests/chapter_19/whole_pipeline/all_types/listing_19_5_more_types.c @@ -0,0 +1,44 @@ +/* A variation on listing_19_5.c with types other than int */ + +// make flag a global variable rather than a parameter +// so we don't have any instructions setting up function parameters, +// e.g. movl %edi, -4(%rbp), which the test script will complain about +double flag = 12e5; + +struct inner { + double a; + double b; +}; + +struct s { + void *ptr; + long arr[5]; + struct inner x; + char c[4]; +}; + +long target(void) { + unsigned long x = 4; + char z; + struct s my_struct = {&z, + { + 1l, + 2l, + }, + {3., 4.}, + "abc"}; + if (4 - x) { + x = my_struct.c[2]; + z = my_struct.arr[1]; + my_struct.x.a = z * 100.; + } + if (!flag) { + z = 10 + *(int *)my_struct.ptr; + } + z = x + 5; + return z; +} + +int main(void) { + return target(); +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/not_char.c b/tests/chapter_19/whole_pipeline/all_types/not_char.c deleted file mode 100644 index 5e3e52ec..00000000 --- a/tests/chapter_19/whole_pipeline/all_types/not_char.c +++ /dev/null @@ -1,16 +0,0 @@ -#ifdef SUPPRESS_WARNINGS -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wconstant-conversion" -#else -#pragma GCC diagnostic ignored "-Woverflow" -#endif -#endif - -int target(void) { - char x = 256; - return !x; -} - -int main(void) { - return target(); -} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/signed_unsigned_conversion.c b/tests/chapter_19/whole_pipeline/all_types/signed_unsigned_conversion.c index 6de1a618..9b8c1766 100644 --- a/tests/chapter_19/whole_pipeline/all_types/signed_unsigned_conversion.c +++ b/tests/chapter_19/whole_pipeline/all_types/signed_unsigned_conversion.c @@ -1,12 +1,50 @@ -// test that we can constant fold casts b/t int and uint, allowing for further -// copy propagation +/* Test constant-folding of conversions between signed and unsigned types + * of the same size, allowing for further copy propagation + * */ -unsigned int target(void) { +unsigned int target_int_to_uint(void) { int i = -1; + // after constant folding this cast, we can propagate the value of u + // into the return statement unsigned int u = (unsigned)i; - return u - 10; + return u / 10u; +} + +int target_uint_to_int(void) { + unsigned int u = 4294967295U; + // after constant folding this cast, we can propagate the value of i + // into the return statement + int i = (int)u; // -1; + return (i + 1) ? 0 : i * 2; +} + +long target_ulong_to_long(void) { + unsigned long ul = 9223372036854775900ul; + // after constant folding this cast, we can propagate the value of l + // into the return statement + signed long l = (long)ul; + return l / 4; +} + +unsigned long target_long_to_ulong(void) { + long l = -200l; + unsigned long ul = (unsigned long)l; + return ul / 10; } int main(void) { - return target() == 4294967285u; + if (target_int_to_uint() != 429496729u) { + return 1; // fail + } + if (target_uint_to_int() != -2) { + return 2; // fail + } + if (target_ulong_to_long() != -2305843009213693929) { + return 3; // fail + } + if (target_long_to_ulong() != 1844674407370955141ul) { + return 4; // fail + } + + return 0; // success } \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/unsigned_compare.c b/tests/chapter_19/whole_pipeline/all_types/unsigned_compare.c deleted file mode 100644 index 95721634..00000000 --- a/tests/chapter_19/whole_pipeline/all_types/unsigned_compare.c +++ /dev/null @@ -1,8 +0,0 @@ -// really a consatnt-folding test -int target(void) { - return (-1u > 100u); -} - -int main(void) { - return target(); -} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/all_types/unsigned_wraparound.c b/tests/chapter_19/whole_pipeline/all_types/unsigned_wraparound.c deleted file mode 100644 index 5101e41f..00000000 --- a/tests/chapter_19/whole_pipeline/all_types/unsigned_wraparound.c +++ /dev/null @@ -1,8 +0,0 @@ -unsigned int target(void) { - unsigned int i = 10u - 11u; - return i % 5u; -} - -int main(void) { - return target() == 0u; -} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/int_only/dead_condition.c b/tests/chapter_19/whole_pipeline/int_only/dead_condition.c index ed352aaa..6c4d9962 100644 --- a/tests/chapter_19/whole_pipeline/int_only/dead_condition.c +++ b/tests/chapter_19/whole_pipeline/int_only/dead_condition.c @@ -1,12 +1,28 @@ +/* If a variable is only used as the controlling condition for an empty branch + * we can eliminate the branch, then eliminate any updates to that variable, + * because they'll all be dead stores + * */ #if defined SUPPRESS_WARNINGS && !defined __clang__ #pragma GCC diagnostic ignored "-Wempty-body" #endif +// flag is a global variable, not parameters +// so we don't have any instructions setting up function parameters, +// e.g. movl %edi, -4(%rbp), which the test script will complain about +int flag = 1; + int target(void) { - // if we enable DSE and dead code elim, x should go away - int x = 10; + int x = 2; + if (flag) { + x = 20; // this will be a dead store after we remove branch below + // wrap this in an if statement so we don't propagate 20 into + // controlling condition + } + if (x) ; + + // we can eliminate the whole function body except this return statement return 10; } diff --git a/tests/chapter_19/whole_pipeline/int_only/elim_and_copy_prop.c b/tests/chapter_19/whole_pipeline/int_only/elim_and_copy_prop.c index 1c0489d5..07b36ad2 100644 --- a/tests/chapter_19/whole_pipeline/int_only/elim_and_copy_prop.c +++ b/tests/chapter_19/whole_pipeline/int_only/elim_and_copy_prop.c @@ -1,8 +1,9 @@ -int target(void) -{ - // w/ dse and copy prop, look for movl $10, %eax and no other movl $10, whatever - int x = 10; - return x; +/* If we can replace every use of a variabe with its value, + * we can delete the copy to that variable + * */ +int target(void) { + int x = 10; // delete this after copy prop rewrites return + return x; // rewrite as 'return x' via copy prop } int main(void) { diff --git a/tests/chapter_19/whole_pipeline/int_only/int_min.c b/tests/chapter_19/whole_pipeline/int_only/int_min.c new file mode 100644 index 00000000..c8901680 --- /dev/null +++ b/tests/chapter_19/whole_pipeline/int_only/int_min.c @@ -0,0 +1,11 @@ +/* Test constant-folding with INT_MIN */ +int target(void) { + return -2147483647 - 1; +} + +int main(void) { + if (~target() != 2147483647) { + return 1; // fail + } + return 0; +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/int_only/listing_19_5.c b/tests/chapter_19/whole_pipeline/int_only/listing_19_5.c new file mode 100644 index 00000000..f2e78ef6 --- /dev/null +++ b/tests/chapter_19/whole_pipeline/int_only/listing_19_5.c @@ -0,0 +1,24 @@ +/* Test case that produces TACKY similar to Listing 19-5; + * this should be optimized to a single "Return 9" instruction */ + +// make flag a global variable rather than a parameter +// so we don't have any instructions setting up function parameters, +// e.g. movl %edi, -4(%rbp), which the test script will complain about +int flag = 1; + +int target(void) { + int x = 4; + int z; + if (4 - x) { + x = 3; + } + if (!flag) { + z = 10; + } + z = x + 5; + return z; +} + +int main(void) { + return target(); +} \ No newline at end of file diff --git a/tests/chapter_19/whole_pipeline/int_only/remainder_test.c b/tests/chapter_19/whole_pipeline/int_only/remainder_test.c index f61d5b3a..c7f5af6f 100644 --- a/tests/chapter_19/whole_pipeline/int_only/remainder_test.c +++ b/tests/chapter_19/whole_pipeline/int_only/remainder_test.c @@ -1,14 +1,30 @@ -/* Make sure we evaluate the % operator as remainder and not modulo. - * This is really a constant folding test but requires copy propagation +/* Make sure we evaluate the % operator correctly for negative numbers. + * In C, the remainder n % d always takes the same sign as n. + * In some languages (e.g. Python), % is the modulo operation, where + * the result always takes the same sign a d. + * + * This test makes sure that we evaluate % as a remainder rather than modulo + * operation during constant folding. + * More info: + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder + * Also note that not everyone uses exactly the same terminolgy here - + * e.g. Python's documentation says "The % (modulo) operator yields the + * remainder from the division of the first argument by the second." + * + * This is basically a constant folding test, but requires copy propagation * so that we can perform constant folding with negative numbers - */ + * */ int target(void) { - // the remainder of 6 % -5 is 1 - // 1 = 6 - (-5) * (-1) - // but 6 modulo -5 is - - // -4 = 6 - (-5) * (-2) + /* The result of the remainder operation 6 % -5 is 1, + * but 6 modulo -5 is -4. + */ return 6 % -5; } -int main(void) { return target(); } \ No newline at end of file +int main(void) { + if (target() != 1) { + return 1; // fail + } + return 0; // success +} \ No newline at end of file