| author | |
| committer | |
| log | d75fa86d7084bd41f68d1cd03763bd7cf2a87052 |
| tree | b454c3e13d627220cdff9a9245849a6ffd57aaa5 |
| parent | 585c160c2022d71197a3ce1399818372371c23a4 |
14 files changed, 495 insertions(+), 123 deletions(-)
lib/compiler_rt/int_to_float_test.zig+1| ... | ... | @@ -813,6 +813,7 @@ test "conversion to f32" { |
| 813 | 813 | test "conversion to f80" { |
| 814 | 814 | if (builtin.zig_backend == .stage1 and builtin.cpu.arch != .x86_64) |
| 815 | 815 | return error.SkipZigTest; // https://github.com/ziglang/zig/issues/11408 |
| 816 | if (std.debug.runtime_safety) return error.SkipZigTest; | |
| 816 | 817 | |
| 817 | 818 | const intToFloat = @import("./int_to_float.zig").intToFloat; |
| 818 | 819 |
src/Air.zig+81-16| ... | ... | @@ -38,11 +38,15 @@ pub const Inst = struct { |
| 38 | 38 | /// is the same as both operands. |
| 39 | 39 | /// Uses the `bin_op` field. |
| 40 | 40 | add, |
| 41 | /// Same as `add` with optimized float mode. | |
| 42 | add_optimized, | |
| 41 | 43 | /// Integer addition. Wrapping is defined to be twos complement wrapping. |
| 42 | 44 | /// Both operands are guaranteed to be the same type, and the result type |
| 43 | 45 | /// is the same as both operands. |
| 44 | 46 | /// Uses the `bin_op` field. |
| 45 | 47 | addwrap, |
| 48 | /// Same as `addwrap` with optimized float mode. | |
| 49 | addwrap_optimized, | |
| 46 | 50 | /// Saturating integer addition. |
| 47 | 51 | /// Both operands are guaranteed to be the same type, and the result type |
| 48 | 52 | /// is the same as both operands. |
| ... | ... | @@ -53,11 +57,15 @@ pub const Inst = struct { |
| 53 | 57 | /// is the same as both operands. |
| 54 | 58 | /// Uses the `bin_op` field. |
| 55 | 59 | sub, |
| 60 | /// Same as `sub` with optimized float mode. | |
| 61 | sub_optimized, | |
| 56 | 62 | /// Integer subtraction. Wrapping is defined to be twos complement wrapping. |
| 57 | 63 | /// Both operands are guaranteed to be the same type, and the result type |
| 58 | 64 | /// is the same as both operands. |
| 59 | 65 | /// Uses the `bin_op` field. |
| 60 | 66 | subwrap, |
| 67 | /// Same as `sub` with optimized float mode. | |
| 68 | subwrap_optimized, | |
| 61 | 69 | /// Saturating integer subtraction. |
| 62 | 70 | /// Both operands are guaranteed to be the same type, and the result type |
| 63 | 71 | /// is the same as both operands. |
| ... | ... | @@ -68,11 +76,15 @@ pub const Inst = struct { |
| 68 | 76 | /// is the same as both operands. |
| 69 | 77 | /// Uses the `bin_op` field. |
| 70 | 78 | mul, |
| 79 | /// Same as `mul` with optimized float mode. | |
| 80 | mul_optimized, | |
| 71 | 81 | /// Integer multiplication. Wrapping is defined to be twos complement wrapping. |
| 72 | 82 | /// Both operands are guaranteed to be the same type, and the result type |
| 73 | 83 | /// is the same as both operands. |
| 74 | 84 | /// Uses the `bin_op` field. |
| 75 | 85 | mulwrap, |
| 86 | /// Same as `mulwrap` with optimized float mode. | |
| 87 | mulwrap_optimized, | |
| 76 | 88 | /// Saturating integer multiplication. |
| 77 | 89 | /// Both operands are guaranteed to be the same type, and the result type |
| 78 | 90 | /// is the same as both operands. |
| ... | ... | @@ -83,32 +95,44 @@ pub const Inst = struct { |
| 83 | 95 | /// is the same as both operands. |
| 84 | 96 | /// Uses the `bin_op` field. |
| 85 | 97 | div_float, |
| 98 | /// Same as `div_float` with optimized float mode. | |
| 99 | div_float_optimized, | |
| 86 | 100 | /// Truncating integer or float division. For integers, wrapping is undefined behavior. |
| 87 | 101 | /// Both operands are guaranteed to be the same type, and the result type |
| 88 | 102 | /// is the same as both operands. |
| 89 | 103 | /// Uses the `bin_op` field. |
| 90 | 104 | div_trunc, |
| 105 | /// Same as `div_trunc` with optimized float mode. | |
| 106 | div_trunc_optimized, | |
| 91 | 107 | /// Flooring integer or float division. For integers, wrapping is undefined behavior. |
| 92 | 108 | /// Both operands are guaranteed to be the same type, and the result type |
| 93 | 109 | /// is the same as both operands. |
| 94 | 110 | /// Uses the `bin_op` field. |
| 95 | 111 | div_floor, |
| 112 | /// Same as `div_floor` with optimized float mode. | |
| 113 | div_floor_optimized, | |
| 96 | 114 | /// Integer or float division. Guaranteed no remainder. |
| 97 | 115 | /// For integers, wrapping is undefined behavior. |
| 98 | 116 | /// Both operands are guaranteed to be the same type, and the result type |
| 99 | 117 | /// is the same as both operands. |
| 100 | 118 | /// Uses the `bin_op` field. |
| 101 | 119 | div_exact, |
| 120 | /// Same as `div_exact` with optimized float mode. | |
| 121 | div_exact_optimized, | |
| 102 | 122 | /// Integer or float remainder division. |
| 103 | 123 | /// Both operands are guaranteed to be the same type, and the result type |
| 104 | 124 | /// is the same as both operands. |
| 105 | 125 | /// Uses the `bin_op` field. |
| 106 | 126 | rem, |
| 127 | /// Same as `rem` with optimized float mode. | |
| 128 | rem_optimized, | |
| 107 | 129 | /// Integer or float modulus division. |
| 108 | 130 | /// Both operands are guaranteed to be the same type, and the result type |
| 109 | 131 | /// is the same as both operands. |
| 110 | 132 | /// Uses the `bin_op` field. |
| 111 | 133 | mod, |
| 134 | /// Same as `mod` with optimized float mode. | |
| 135 | mod_optimized, | |
| 112 | 136 | /// Add an offset to a pointer, returning a new pointer. |
| 113 | 137 | /// The offset is in element type units, not bytes. |
| 114 | 138 | /// Wrapping is undefined behavior. |
| ... | ... | @@ -293,29 +317,45 @@ pub const Inst = struct { |
| 293 | 317 | /// LHS of zero. |
| 294 | 318 | /// Uses the `un_op` field. |
| 295 | 319 | neg, |
| 320 | /// Same as `neg` with optimized float mode. | |
| 321 | neg_optimized, | |
| 296 | 322 | |
| 297 | 323 | /// `<`. Result type is always bool. |
| 298 | 324 | /// Uses the `bin_op` field. |
| 299 | 325 | cmp_lt, |
| 326 | /// Same as `cmp_lt` with optimized float mode. | |
| 327 | cmp_lt_optimized, | |
| 300 | 328 | /// `<=`. Result type is always bool. |
| 301 | 329 | /// Uses the `bin_op` field. |
| 302 | 330 | cmp_lte, |
| 331 | /// Same as `cmp_lte` with optimized float mode. | |
| 332 | cmp_lte_optimized, | |
| 303 | 333 | /// `==`. Result type is always bool. |
| 304 | 334 | /// Uses the `bin_op` field. |
| 305 | 335 | cmp_eq, |
| 336 | /// Same as `cmp_eq` with optimized float mode. | |
| 337 | cmp_eq_optimized, | |
| 306 | 338 | /// `>=`. Result type is always bool. |
| 307 | 339 | /// Uses the `bin_op` field. |
| 308 | 340 | cmp_gte, |
| 341 | /// Same as `cmp_gte` with optimized float mode. | |
| 342 | cmp_gte_optimized, | |
| 309 | 343 | /// `>`. Result type is always bool. |
| 310 | 344 | /// Uses the `bin_op` field. |
| 311 | 345 | cmp_gt, |
| 346 | /// Same as `cmp_gt` with optimized float mode. | |
| 347 | cmp_gt_optimized, | |
| 312 | 348 | /// `!=`. Result type is always bool. |
| 313 | 349 | /// Uses the `bin_op` field. |
| 314 | 350 | cmp_neq, |
| 351 | /// Same as `cmp_neq` with optimized float mode. | |
| 352 | cmp_neq_optimized, | |
| 315 | 353 | /// Conditional between two vectors. |
| 316 | 354 | /// Result type is always a vector of bools. |
| 317 | 355 | /// Uses the `ty_pl` field, payload is `VectorCmp`. |
| 318 | 356 | cmp_vector, |
| 357 | /// Same as `cmp_vector` with optimized float mode. | |
| 358 | cmp_vector_optimized, | |
| 319 | 359 | |
| 320 | 360 | /// Conditional branch. |
| 321 | 361 | /// Result type is always noreturn; no instructions in a block follow this one. |
| ... | ... | @@ -553,6 +593,8 @@ pub const Inst = struct { |
| 553 | 593 | /// Given a float operand, return the integer with the closest mathematical meaning. |
| 554 | 594 | /// Uses the `ty_op` field. |
| 555 | 595 | float_to_int, |
| 596 | /// Same as `float_to_int` with optimized float mode. | |
| 597 | float_to_int_optimized, | |
| 556 | 598 | /// Given an integer operand, return the float with the closest mathematical meaning. |
| 557 | 599 | /// Uses the `ty_op` field. |
| 558 | 600 | int_to_float, |
| ... | ... | @@ -564,6 +606,8 @@ pub const Inst = struct { |
| 564 | 606 | /// * min, max, add, mul => integer or float |
| 565 | 607 | /// Uses the `reduce` field. |
| 566 | 608 | reduce, |
| 609 | /// Same as `reduce` with optimized float mode. | |
| 610 | reduce_optimized, | |
| 567 | 611 | /// Given an integer, bool, float, or pointer operand, return a vector with all elements |
| 568 | 612 | /// equal to the scalar value. |
| 569 | 613 | /// Uses the `ty_op` field. |
| ... | ... | @@ -676,25 +720,25 @@ pub const Inst = struct { |
| 676 | 720 | /// Sets the operand as the current error return trace, |
| 677 | 721 | set_err_return_trace, |
| 678 | 722 | |
| 679 | pub fn fromCmpOp(op: std.math.CompareOperator) Tag { | |
| 680 | return switch (op) { | |
| 681 | .lt => .cmp_lt, | |
| 682 | .lte => .cmp_lte, | |
| 683 | .eq => .cmp_eq, | |
| 684 | .gte => .cmp_gte, | |
| 685 | .gt => .cmp_gt, | |
| 686 | .neq => .cmp_neq, | |
| 687 | }; | |
| 723 | pub fn fromCmpOp(op: std.math.CompareOperator, optimized: bool) Tag { | |
| 724 | switch (op) { | |
| 725 | .lt => return if (optimized) .cmp_lt_optimized else .cmp_lt, | |
| 726 | .lte => return if (optimized) .cmp_lte_optimized else .cmp_lte, | |
| 727 | .eq => return if (optimized) .cmp_eq_optimized else .cmp_eq, | |
| 728 | .gte => return if (optimized) .cmp_gte_optimized else .cmp_gte, | |
| 729 | .gt => return if (optimized) .cmp_gt_optimized else .cmp_gt, | |
| 730 | .neq => return if (optimized) .cmp_neq_optimized else .cmp_neq, | |
| 731 | } | |
| 688 | 732 | } |
| 689 | 733 | |
| 690 | 734 | pub fn toCmpOp(tag: Tag) ?std.math.CompareOperator { |
| 691 | 735 | return switch (tag) { |
| 692 | .cmp_lt => .lt, | |
| 693 | .cmp_lte => .lte, | |
| 694 | .cmp_eq => .eq, | |
| 695 | .cmp_gte => .gte, | |
| 696 | .cmp_gt => .gt, | |
| 697 | .cmp_neq => .neq, | |
| 736 | .cmp_lt, .cmp_lt_optimized => .lt, | |
| 737 | .cmp_lte, .cmp_lte_optimized => .lte, | |
| 738 | .cmp_eq, .cmp_eq_optimized => .eq, | |
| 739 | .cmp_gte, .cmp_gte_optimized => .gte, | |
| 740 | .cmp_gt, .cmp_gt_optimized => .gt, | |
| 741 | .cmp_neq, .cmp_neq_optimized => .neq, | |
| 698 | 742 | else => null, |
| 699 | 743 | }; |
| 700 | 744 | } |
| ... | ... | @@ -959,6 +1003,18 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { |
| 959 | 1003 | .max, |
| 960 | 1004 | .bool_and, |
| 961 | 1005 | .bool_or, |
| 1006 | .add_optimized, | |
| 1007 | .addwrap_optimized, | |
| 1008 | .sub_optimized, | |
| 1009 | .subwrap_optimized, | |
| 1010 | .mul_optimized, | |
| 1011 | .mulwrap_optimized, | |
| 1012 | .div_float_optimized, | |
| 1013 | .div_trunc_optimized, | |
| 1014 | .div_floor_optimized, | |
| 1015 | .div_exact_optimized, | |
| 1016 | .rem_optimized, | |
| 1017 | .mod_optimized, | |
| 962 | 1018 | => return air.typeOf(datas[inst].bin_op.lhs), |
| 963 | 1019 | |
| 964 | 1020 | .sqrt, |
| ... | ... | @@ -976,6 +1032,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { |
| 976 | 1032 | .round, |
| 977 | 1033 | .trunc_float, |
| 978 | 1034 | .neg, |
| 1035 | .neg_optimized, | |
| 979 | 1036 | => return air.typeOf(datas[inst].un_op), |
| 980 | 1037 | |
| 981 | 1038 | .cmp_lt, |
| ... | ... | @@ -984,6 +1041,12 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { |
| 984 | 1041 | .cmp_gte, |
| 985 | 1042 | .cmp_gt, |
| 986 | 1043 | .cmp_neq, |
| 1044 | .cmp_lt_optimized, | |
| 1045 | .cmp_lte_optimized, | |
| 1046 | .cmp_eq_optimized, | |
| 1047 | .cmp_gte_optimized, | |
| 1048 | .cmp_gt_optimized, | |
| 1049 | .cmp_neq_optimized, | |
| 987 | 1050 | .cmp_lt_errors_len, |
| 988 | 1051 | .is_null, |
| 989 | 1052 | .is_non_null, |
| ... | ... | @@ -1018,6 +1081,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { |
| 1018 | 1081 | .union_init, |
| 1019 | 1082 | .field_parent_ptr, |
| 1020 | 1083 | .cmp_vector, |
| 1084 | .cmp_vector_optimized, | |
| 1021 | 1085 | .add_with_overflow, |
| 1022 | 1086 | .sub_with_overflow, |
| 1023 | 1087 | .mul_with_overflow, |
| ... | ... | @@ -1054,6 +1118,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { |
| 1054 | 1118 | .struct_field_ptr_index_3, |
| 1055 | 1119 | .array_to_slice, |
| 1056 | 1120 | .float_to_int, |
| 1121 | .float_to_int_optimized, | |
| 1057 | 1122 | .int_to_float, |
| 1058 | 1123 | .splat, |
| 1059 | 1124 | .get_union_tag, |
| ... | ... | @@ -1129,7 +1194,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { |
| 1129 | 1194 | return ptr_ty.elemType(); |
| 1130 | 1195 | }, |
| 1131 | 1196 | |
| 1132 | .reduce => return air.typeOf(datas[inst].reduce.operand).childType(), | |
| 1197 | .reduce, .reduce_optimized => return air.typeOf(datas[inst].reduce.operand).childType(), | |
| 1133 | 1198 | |
| 1134 | 1199 | .mul_add => return air.typeOf(datas[inst].pl_op.operand), |
| 1135 | 1200 | .select => { |
src/Liveness.zig+44-4| ... | ... | @@ -173,6 +173,25 @@ pub fn categorizeOperand( |
| 173 | 173 | .shr_exact, |
| 174 | 174 | .min, |
| 175 | 175 | .max, |
| 176 | .add_optimized, | |
| 177 | .addwrap_optimized, | |
| 178 | .sub_optimized, | |
| 179 | .subwrap_optimized, | |
| 180 | .mul_optimized, | |
| 181 | .mulwrap_optimized, | |
| 182 | .div_float_optimized, | |
| 183 | .div_trunc_optimized, | |
| 184 | .div_floor_optimized, | |
| 185 | .div_exact_optimized, | |
| 186 | .rem_optimized, | |
| 187 | .mod_optimized, | |
| 188 | .neg_optimized, | |
| 189 | .cmp_lt_optimized, | |
| 190 | .cmp_lte_optimized, | |
| 191 | .cmp_eq_optimized, | |
| 192 | .cmp_gte_optimized, | |
| 193 | .cmp_gt_optimized, | |
| 194 | .cmp_neq_optimized, | |
| 176 | 195 | => { |
| 177 | 196 | const o = air_datas[inst].bin_op; |
| 178 | 197 | if (o.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none); |
| ... | ... | @@ -239,6 +258,7 @@ pub fn categorizeOperand( |
| 239 | 258 | .struct_field_ptr_index_3, |
| 240 | 259 | .array_to_slice, |
| 241 | 260 | .float_to_int, |
| 261 | .float_to_int_optimized, | |
| 242 | 262 | .int_to_float, |
| 243 | 263 | .get_union_tag, |
| 244 | 264 | .clz, |
| ... | ... | @@ -381,12 +401,12 @@ pub fn categorizeOperand( |
| 381 | 401 | if (extra.b == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none); |
| 382 | 402 | return .none; |
| 383 | 403 | }, |
| 384 | .reduce => { | |
| 404 | .reduce, .reduce_optimized => { | |
| 385 | 405 | const reduce = air_datas[inst].reduce; |
| 386 | 406 | if (reduce.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none); |
| 387 | 407 | return .none; |
| 388 | 408 | }, |
| 389 | .cmp_vector => { | |
| 409 | .cmp_vector, .cmp_vector_optimized => { | |
| 390 | 410 | const extra = air.extraData(Air.VectorCmp, air_datas[inst].ty_pl.payload).data; |
| 391 | 411 | if (extra.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none); |
| 392 | 412 | if (extra.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none); |
| ... | ... | @@ -701,29 +721,47 @@ fn analyzeInst( |
| 701 | 721 | |
| 702 | 722 | switch (inst_tags[inst]) { |
| 703 | 723 | .add, |
| 724 | .add_optimized, | |
| 704 | 725 | .addwrap, |
| 726 | .addwrap_optimized, | |
| 705 | 727 | .add_sat, |
| 706 | 728 | .sub, |
| 729 | .sub_optimized, | |
| 707 | 730 | .subwrap, |
| 731 | .subwrap_optimized, | |
| 708 | 732 | .sub_sat, |
| 709 | 733 | .mul, |
| 734 | .mul_optimized, | |
| 710 | 735 | .mulwrap, |
| 736 | .mulwrap_optimized, | |
| 711 | 737 | .mul_sat, |
| 712 | 738 | .div_float, |
| 739 | .div_float_optimized, | |
| 713 | 740 | .div_trunc, |
| 741 | .div_trunc_optimized, | |
| 714 | 742 | .div_floor, |
| 743 | .div_floor_optimized, | |
| 715 | 744 | .div_exact, |
| 745 | .div_exact_optimized, | |
| 716 | 746 | .rem, |
| 747 | .rem_optimized, | |
| 717 | 748 | .mod, |
| 749 | .mod_optimized, | |
| 718 | 750 | .bit_and, |
| 719 | 751 | .bit_or, |
| 720 | 752 | .xor, |
| 721 | 753 | .cmp_lt, |
| 754 | .cmp_lt_optimized, | |
| 722 | 755 | .cmp_lte, |
| 756 | .cmp_lte_optimized, | |
| 723 | 757 | .cmp_eq, |
| 758 | .cmp_eq_optimized, | |
| 724 | 759 | .cmp_gte, |
| 760 | .cmp_gte_optimized, | |
| 725 | 761 | .cmp_gt, |
| 762 | .cmp_gt_optimized, | |
| 726 | 763 | .cmp_neq, |
| 764 | .cmp_neq_optimized, | |
| 727 | 765 | .bool_and, |
| 728 | 766 | .bool_or, |
| 729 | 767 | .store, |
| ... | ... | @@ -794,6 +832,7 @@ fn analyzeInst( |
| 794 | 832 | .struct_field_ptr_index_3, |
| 795 | 833 | .array_to_slice, |
| 796 | 834 | .float_to_int, |
| 835 | .float_to_int_optimized, | |
| 797 | 836 | .int_to_float, |
| 798 | 837 | .get_union_tag, |
| 799 | 838 | .clz, |
| ... | ... | @@ -836,6 +875,7 @@ fn analyzeInst( |
| 836 | 875 | .round, |
| 837 | 876 | .trunc_float, |
| 838 | 877 | .neg, |
| 878 | .neg_optimized, | |
| 839 | 879 | .cmp_lt_errors_len, |
| 840 | 880 | .set_err_return_trace, |
| 841 | 881 | => { |
| ... | ... | @@ -903,11 +943,11 @@ fn analyzeInst( |
| 903 | 943 | const extra = a.air.extraData(Air.Shuffle, inst_datas[inst].ty_pl.payload).data; |
| 904 | 944 | return trackOperands(a, new_set, inst, main_tomb, .{ extra.a, extra.b, .none }); |
| 905 | 945 | }, |
| 906 | .reduce => { | |
| 946 | .reduce, .reduce_optimized => { | |
| 907 | 947 | const reduce = inst_datas[inst].reduce; |
| 908 | 948 | return trackOperands(a, new_set, inst, main_tomb, .{ reduce.operand, .none, .none }); |
| 909 | 949 | }, |
| 910 | .cmp_vector => { | |
| 950 | .cmp_vector, .cmp_vector_optimized => { | |
| 911 | 951 | const extra = a.air.extraData(Air.VectorCmp, inst_datas[inst].ty_pl.payload).data; |
| 912 | 952 | return trackOperands(a, new_set, inst, main_tomb, .{ extra.lhs, extra.rhs, .none }); |
| 913 | 953 | }, |
src/Sema.zig+81-61| ... | ... | @@ -144,6 +144,9 @@ pub const Block = struct { |
| 144 | 144 | /// when null, it is determined by build mode, changed by @setRuntimeSafety |
| 145 | 145 | want_safety: ?bool = null, |
| 146 | 146 | |
| 147 | /// What mode to generate float operations in, set by @setFloatMode | |
| 148 | float_mode: std.builtin.FloatMode = .Strict, | |
| 149 | ||
| 147 | 150 | c_import_buf: ?*std.ArrayList(u8) = null, |
| 148 | 151 | |
| 149 | 152 | /// type of `err` in `else => |err|` |
| ... | ... | @@ -206,6 +209,7 @@ pub const Block = struct { |
| 206 | 209 | .runtime_loop = parent.runtime_loop, |
| 207 | 210 | .runtime_index = parent.runtime_index, |
| 208 | 211 | .want_safety = parent.want_safety, |
| 212 | .float_mode = parent.float_mode, | |
| 209 | 213 | .c_import_buf = parent.c_import_buf, |
| 210 | 214 | .switch_else_err_ty = parent.switch_else_err_ty, |
| 211 | 215 | }; |
| ... | ... | @@ -414,7 +418,7 @@ pub const Block = struct { |
| 414 | 418 | |
| 415 | 419 | fn addCmpVector(block: *Block, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, cmp_op: std.math.CompareOperator, vector_ty: Air.Inst.Ref) !Air.Inst.Ref { |
| 416 | 420 | return block.addInst(.{ |
| 417 | .tag = .cmp_vector, | |
| 421 | .tag = if (block.float_mode == .Optimized) .cmp_vector_optimized else .cmp_vector, | |
| 418 | 422 | .data = .{ .ty_pl = .{ |
| 419 | 423 | .ty = vector_ty, |
| 420 | 424 | .payload = try block.sema.addExtra(Air.VectorCmp{ |
| ... | ... | @@ -714,10 +718,10 @@ fn analyzeBodyInner( |
| 714 | 718 | .closure_get => try sema.zirClosureGet(block, inst), |
| 715 | 719 | .cmp_lt => try sema.zirCmp(block, inst, .lt), |
| 716 | 720 | .cmp_lte => try sema.zirCmp(block, inst, .lte), |
| 717 | .cmp_eq => try sema.zirCmpEq(block, inst, .eq, .cmp_eq), | |
| 721 | .cmp_eq => try sema.zirCmpEq(block, inst, .eq, Air.Inst.Tag.fromCmpOp(.eq, block.float_mode == .Optimized)), | |
| 718 | 722 | .cmp_gte => try sema.zirCmp(block, inst, .gte), |
| 719 | 723 | .cmp_gt => try sema.zirCmp(block, inst, .gt), |
| 720 | .cmp_neq => try sema.zirCmpEq(block, inst, .neq, .cmp_neq), | |
| 724 | .cmp_neq => try sema.zirCmpEq(block, inst, .neq, Air.Inst.Tag.fromCmpOp(.neq, block.float_mode == .Optimized)), | |
| 721 | 725 | .coerce_result_ptr => try sema.zirCoerceResultPtr(block, inst), |
| 722 | 726 | .decl_ref => try sema.zirDeclRef(block, inst), |
| 723 | 727 | .decl_val => try sema.zirDeclVal(block, inst), |
| ... | ... | @@ -4705,6 +4709,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro |
| 4705 | 4709 | .inlining = parent_block.inlining, |
| 4706 | 4710 | .is_comptime = parent_block.is_comptime, |
| 4707 | 4711 | .want_safety = parent_block.want_safety, |
| 4712 | .float_mode = parent_block.float_mode, | |
| 4708 | 4713 | }; |
| 4709 | 4714 | |
| 4710 | 4715 | defer child_block.instructions.deinit(gpa); |
| ... | ... | @@ -5042,13 +5047,7 @@ fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi |
| 5042 | 5047 | fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { |
| 5043 | 5048 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 5044 | 5049 | const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 5045 | const float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode", "operand to @setFloatMode must be comptime known"); | |
| 5046 | switch (float_mode) { | |
| 5047 | .Strict => return, | |
| 5048 | .Optimized => { | |
| 5049 | // TODO implement optimized float mode | |
| 5050 | }, | |
| 5051 | } | |
| 5050 | block.float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode", "operand to @setFloatMode must be comptime known"); | |
| 5052 | 5051 | } |
| 5053 | 5052 | |
| 5054 | 5053 | fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| ... | ... | @@ -8092,7 +8091,7 @@ fn intCast( |
| 8092 | 8091 | const ok = if (is_vector) ok: { |
| 8093 | 8092 | const is_in_range = try block.addCmpVector(diff_unsigned, dest_range, .lte, try sema.addType(operand_ty)); |
| 8094 | 8093 | const all_in_range = try block.addInst(.{ |
| 8095 | .tag = .reduce, | |
| 8094 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, | |
| 8096 | 8095 | .data = .{ .reduce = .{ |
| 8097 | 8096 | .operand = is_in_range, |
| 8098 | 8097 | .operation = .And, |
| ... | ... | @@ -8109,7 +8108,7 @@ fn intCast( |
| 8109 | 8108 | const ok = if (is_vector) ok: { |
| 8110 | 8109 | const is_in_range = try block.addCmpVector(diff, dest_max, .lte, try sema.addType(operand_ty)); |
| 8111 | 8110 | const all_in_range = try block.addInst(.{ |
| 8112 | .tag = .reduce, | |
| 8111 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, | |
| 8113 | 8112 | .data = .{ .reduce = .{ |
| 8114 | 8113 | .operand = is_in_range, |
| 8115 | 8114 | .operation = .And, |
| ... | ... | @@ -8130,7 +8129,7 @@ fn intCast( |
| 8130 | 8129 | const zero_inst = try sema.addConstant(operand_ty, zero_val); |
| 8131 | 8130 | const is_in_range = try block.addCmpVector(operand, zero_inst, .gte, try sema.addType(operand_ty)); |
| 8132 | 8131 | const all_in_range = try block.addInst(.{ |
| 8133 | .tag = .reduce, | |
| 8132 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, | |
| 8134 | 8133 | .data = .{ .reduce = .{ |
| 8135 | 8134 | .operand = is_in_range, |
| 8136 | 8135 | .operation = .And, |
| ... | ... | @@ -9391,7 +9390,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9391 | 9390 | } else { |
| 9392 | 9391 | for (items) |item_ref| { |
| 9393 | 9392 | const item = try sema.resolveInst(item_ref); |
| 9394 | const cmp_ok = try case_block.addBinOp(.cmp_eq, operand, item); | |
| 9393 | const cmp_ok = try case_block.addBinOp(if (case_block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, operand, item); | |
| 9395 | 9394 | if (any_ok != .none) { |
| 9396 | 9395 | any_ok = try case_block.addBinOp(.bool_or, any_ok, cmp_ok); |
| 9397 | 9396 | } else { |
| ... | ... | @@ -9411,12 +9410,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9411 | 9410 | |
| 9412 | 9411 | // operand >= first and operand <= last |
| 9413 | 9412 | const range_first_ok = try case_block.addBinOp( |
| 9414 | .cmp_gte, | |
| 9413 | if (case_block.float_mode == .Optimized) .cmp_gte_optimized else .cmp_gte, | |
| 9415 | 9414 | operand, |
| 9416 | 9415 | item_first, |
| 9417 | 9416 | ); |
| 9418 | 9417 | const range_last_ok = try case_block.addBinOp( |
| 9419 | .cmp_lte, | |
| 9418 | if (case_block.float_mode == .Optimized) .cmp_lte_optimized else .cmp_lte, | |
| 9420 | 9419 | operand, |
| 9421 | 9420 | item_last, |
| 9422 | 9421 | ); |
| ... | ... | @@ -10023,7 +10022,7 @@ fn zirShl( |
| 10023 | 10022 | const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty); |
| 10024 | 10023 | const any_ov_bit = if (lhs_ty.zigTypeTag() == .Vector) |
| 10025 | 10024 | try block.addInst(.{ |
| 10026 | .tag = .reduce, | |
| 10025 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, | |
| 10027 | 10026 | .data = .{ .reduce = .{ |
| 10028 | 10027 | .operand = ov_bit, |
| 10029 | 10028 | .operation = .Or, |
| ... | ... | @@ -10120,7 +10119,7 @@ fn zirShr( |
| 10120 | 10119 | const ok = if (rhs_ty.zigTypeTag() == .Vector) ok: { |
| 10121 | 10120 | const eql = try block.addCmpVector(lhs, back, .eq, try sema.addType(rhs_ty)); |
| 10122 | 10121 | break :ok try block.addInst(.{ |
| 10123 | .tag = .reduce, | |
| 10122 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, | |
| 10124 | 10123 | .data = .{ .reduce = .{ |
| 10125 | 10124 | .operand = eql, |
| 10126 | 10125 | .operation = .And, |
| ... | ... | @@ -10719,7 +10718,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 10719 | 10718 | return sema.addConstant(rhs_ty, try rhs_val.floatNeg(rhs_ty, sema.arena, target)); |
| 10720 | 10719 | } |
| 10721 | 10720 | try sema.requireRuntimeBlock(block, src, null); |
| 10722 | return block.addUnOp(.neg, rhs); | |
| 10721 | return block.addUnOp(if (block.float_mode == .Optimized) .neg_optimized else .neg, rhs); | |
| 10723 | 10722 | } |
| 10724 | 10723 | |
| 10725 | 10724 | const lhs = if (rhs_ty.zigTypeTag() == .Vector) |
| ... | ... | @@ -11078,6 +11077,7 @@ fn analyzeArithmetic( |
| 11078 | 11077 | return casted_lhs; |
| 11079 | 11078 | } |
| 11080 | 11079 | } |
| 11080 | const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .add_optimized else .add; | |
| 11081 | 11081 | if (maybe_lhs_val) |lhs_val| { |
| 11082 | 11082 | if (lhs_val.isUndef()) { |
| 11083 | 11083 | if (is_int) { |
| ... | ... | @@ -11100,8 +11100,8 @@ fn analyzeArithmetic( |
| 11100 | 11100 | try sema.floatAdd(lhs_val, rhs_val, resolved_type), |
| 11101 | 11101 | ); |
| 11102 | 11102 | } |
| 11103 | } else break :rs .{ .src = rhs_src, .air_tag = .add }; | |
| 11104 | } else break :rs .{ .src = lhs_src, .air_tag = .add }; | |
| 11103 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; | |
| 11104 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; | |
| 11105 | 11105 | }, |
| 11106 | 11106 | .addwrap => { |
| 11107 | 11107 | // Integers only; floats are checked above. |
| ... | ... | @@ -11112,6 +11112,7 @@ fn analyzeArithmetic( |
| 11112 | 11112 | return casted_rhs; |
| 11113 | 11113 | } |
| 11114 | 11114 | } |
| 11115 | const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .addwrap_optimized else .addwrap; | |
| 11115 | 11116 | if (maybe_rhs_val) |rhs_val| { |
| 11116 | 11117 | if (rhs_val.isUndef()) { |
| 11117 | 11118 | return sema.addConstUndef(resolved_type); |
| ... | ... | @@ -11124,8 +11125,8 @@ fn analyzeArithmetic( |
| 11124 | 11125 | resolved_type, |
| 11125 | 11126 | try sema.numberAddWrap(block, src, lhs_val, rhs_val, resolved_type), |
| 11126 | 11127 | ); |
| 11127 | } else break :rs .{ .src = lhs_src, .air_tag = .addwrap }; | |
| 11128 | } else break :rs .{ .src = rhs_src, .air_tag = .addwrap }; | |
| 11128 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; | |
| 11129 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; | |
| 11129 | 11130 | }, |
| 11130 | 11131 | .add_sat => { |
| 11131 | 11132 | // Integers only; floats are checked above. |
| ... | ... | @@ -11173,6 +11174,7 @@ fn analyzeArithmetic( |
| 11173 | 11174 | return casted_lhs; |
| 11174 | 11175 | } |
| 11175 | 11176 | } |
| 11177 | const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .sub_optimized else .sub; | |
| 11176 | 11178 | if (maybe_lhs_val) |lhs_val| { |
| 11177 | 11179 | if (lhs_val.isUndef()) { |
| 11178 | 11180 | if (is_int) { |
| ... | ... | @@ -11195,8 +11197,8 @@ fn analyzeArithmetic( |
| 11195 | 11197 | try sema.floatSub(lhs_val, rhs_val, resolved_type), |
| 11196 | 11198 | ); |
| 11197 | 11199 | } |
| 11198 | } else break :rs .{ .src = rhs_src, .air_tag = .sub }; | |
| 11199 | } else break :rs .{ .src = lhs_src, .air_tag = .sub }; | |
| 11200 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; | |
| 11201 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; | |
| 11200 | 11202 | }, |
| 11201 | 11203 | .subwrap => { |
| 11202 | 11204 | // Integers only; floats are checked above. |
| ... | ... | @@ -11210,6 +11212,7 @@ fn analyzeArithmetic( |
| 11210 | 11212 | return casted_lhs; |
| 11211 | 11213 | } |
| 11212 | 11214 | } |
| 11215 | const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .subwrap_optimized else .subwrap; | |
| 11213 | 11216 | if (maybe_lhs_val) |lhs_val| { |
| 11214 | 11217 | if (lhs_val.isUndef()) { |
| 11215 | 11218 | return sema.addConstUndef(resolved_type); |
| ... | ... | @@ -11219,8 +11222,8 @@ fn analyzeArithmetic( |
| 11219 | 11222 | resolved_type, |
| 11220 | 11223 | try sema.numberSubWrap(block, src, lhs_val, rhs_val, resolved_type), |
| 11221 | 11224 | ); |
| 11222 | } else break :rs .{ .src = rhs_src, .air_tag = .subwrap }; | |
| 11223 | } else break :rs .{ .src = lhs_src, .air_tag = .subwrap }; | |
| 11225 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; | |
| 11226 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; | |
| 11224 | 11227 | }, |
| 11225 | 11228 | .sub_sat => { |
| 11226 | 11229 | // Integers only; floats are checked above. |
| ... | ... | @@ -11327,14 +11330,14 @@ fn analyzeArithmetic( |
| 11327 | 11330 | if (is_int) { |
| 11328 | 11331 | break :rs .{ .src = rhs_src, .air_tag = .div_trunc }; |
| 11329 | 11332 | } else { |
| 11330 | break :rs .{ .src = rhs_src, .air_tag = .div_float }; | |
| 11333 | break :rs .{ .src = rhs_src, .air_tag = if (block.float_mode == .Optimized) .div_float_optimized else .div_float }; | |
| 11331 | 11334 | } |
| 11332 | 11335 | } |
| 11333 | 11336 | } else { |
| 11334 | 11337 | if (is_int) { |
| 11335 | 11338 | break :rs .{ .src = lhs_src, .air_tag = .div_trunc }; |
| 11336 | 11339 | } else { |
| 11337 | break :rs .{ .src = lhs_src, .air_tag = .div_float }; | |
| 11340 | break :rs .{ .src = lhs_src, .air_tag = if (block.float_mode == .Optimized) .div_float_optimized else .div_float }; | |
| 11338 | 11341 | } |
| 11339 | 11342 | } |
| 11340 | 11343 | }, |
| ... | ... | @@ -11373,6 +11376,7 @@ fn analyzeArithmetic( |
| 11373 | 11376 | return sema.failWithDivideByZero(block, rhs_src); |
| 11374 | 11377 | } |
| 11375 | 11378 | } |
| 11379 | const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .div_trunc_optimized else .div_trunc; | |
| 11376 | 11380 | if (maybe_lhs_val) |lhs_val| { |
| 11377 | 11381 | if (lhs_val.isUndef()) { |
| 11378 | 11382 | if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) { |
| ... | ... | @@ -11398,8 +11402,8 @@ fn analyzeArithmetic( |
| 11398 | 11402 | try lhs_val.floatDivTrunc(rhs_val, resolved_type, sema.arena, target), |
| 11399 | 11403 | ); |
| 11400 | 11404 | } |
| 11401 | } else break :rs .{ .src = rhs_src, .air_tag = .div_trunc }; | |
| 11402 | } else break :rs .{ .src = lhs_src, .air_tag = .div_trunc }; | |
| 11405 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; | |
| 11406 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; | |
| 11403 | 11407 | }, |
| 11404 | 11408 | .div_floor => { |
| 11405 | 11409 | // For integers: |
| ... | ... | @@ -11436,6 +11440,7 @@ fn analyzeArithmetic( |
| 11436 | 11440 | return sema.failWithDivideByZero(block, rhs_src); |
| 11437 | 11441 | } |
| 11438 | 11442 | } |
| 11443 | const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .div_floor_optimized else .div_floor; | |
| 11439 | 11444 | if (maybe_lhs_val) |lhs_val| { |
| 11440 | 11445 | if (lhs_val.isUndef()) { |
| 11441 | 11446 | if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) { |
| ... | ... | @@ -11461,8 +11466,8 @@ fn analyzeArithmetic( |
| 11461 | 11466 | try lhs_val.floatDivFloor(rhs_val, resolved_type, sema.arena, target), |
| 11462 | 11467 | ); |
| 11463 | 11468 | } |
| 11464 | } else break :rs .{ .src = rhs_src, .air_tag = .div_floor }; | |
| 11465 | } else break :rs .{ .src = lhs_src, .air_tag = .div_floor }; | |
| 11469 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; | |
| 11470 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; | |
| 11466 | 11471 | }, |
| 11467 | 11472 | .div_exact => { |
| 11468 | 11473 | // For integers: |
| ... | ... | @@ -11498,6 +11503,7 @@ fn analyzeArithmetic( |
| 11498 | 11503 | return sema.failWithDivideByZero(block, rhs_src); |
| 11499 | 11504 | } |
| 11500 | 11505 | } |
| 11506 | const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .div_exact_optimized else .div_exact; | |
| 11501 | 11507 | if (maybe_lhs_val) |lhs_val| { |
| 11502 | 11508 | if (maybe_rhs_val) |rhs_val| { |
| 11503 | 11509 | if (is_int) { |
| ... | ... | @@ -11513,8 +11519,8 @@ fn analyzeArithmetic( |
| 11513 | 11519 | try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, target), |
| 11514 | 11520 | ); |
| 11515 | 11521 | } |
| 11516 | } else break :rs .{ .src = rhs_src, .air_tag = .div_exact }; | |
| 11517 | } else break :rs .{ .src = lhs_src, .air_tag = .div_exact }; | |
| 11522 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; | |
| 11523 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; | |
| 11518 | 11524 | }, |
| 11519 | 11525 | .mul => { |
| 11520 | 11526 | // For integers: |
| ... | ... | @@ -11535,6 +11541,7 @@ fn analyzeArithmetic( |
| 11535 | 11541 | } |
| 11536 | 11542 | } |
| 11537 | 11543 | } |
| 11544 | const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .mul_optimized else .mul; | |
| 11538 | 11545 | if (maybe_rhs_val) |rhs_val| { |
| 11539 | 11546 | if (rhs_val.isUndef()) { |
| 11540 | 11547 | if (is_int) { |
| ... | ... | @@ -11570,8 +11577,8 @@ fn analyzeArithmetic( |
| 11570 | 11577 | try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, target), |
| 11571 | 11578 | ); |
| 11572 | 11579 | } |
| 11573 | } else break :rs .{ .src = lhs_src, .air_tag = .mul }; | |
| 11574 | } else break :rs .{ .src = rhs_src, .air_tag = .mul }; | |
| 11580 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; | |
| 11581 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; | |
| 11575 | 11582 | }, |
| 11576 | 11583 | .mulwrap => { |
| 11577 | 11584 | // Integers only; floats are handled above. |
| ... | ... | @@ -11588,6 +11595,7 @@ fn analyzeArithmetic( |
| 11588 | 11595 | } |
| 11589 | 11596 | } |
| 11590 | 11597 | } |
| 11598 | const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .mulwrap_optimized else .mulwrap; | |
| 11591 | 11599 | if (maybe_rhs_val) |rhs_val| { |
| 11592 | 11600 | if (rhs_val.isUndef()) { |
| 11593 | 11601 | return sema.addConstUndef(resolved_type); |
| ... | ... | @@ -11606,8 +11614,8 @@ fn analyzeArithmetic( |
| 11606 | 11614 | resolved_type, |
| 11607 | 11615 | try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, target), |
| 11608 | 11616 | ); |
| 11609 | } else break :rs .{ .src = lhs_src, .air_tag = .mulwrap }; | |
| 11610 | } else break :rs .{ .src = rhs_src, .air_tag = .mulwrap }; | |
| 11617 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; | |
| 11618 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; | |
| 11611 | 11619 | }, |
| 11612 | 11620 | .mul_sat => { |
| 11613 | 11621 | // Integers only; floats are checked above. |
| ... | ... | @@ -11777,6 +11785,7 @@ fn analyzeArithmetic( |
| 11777 | 11785 | return sema.failWithDivideByZero(block, rhs_src); |
| 11778 | 11786 | } |
| 11779 | 11787 | } |
| 11788 | const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .rem_optimized else .rem; | |
| 11780 | 11789 | if (maybe_lhs_val) |lhs_val| { |
| 11781 | 11790 | if (lhs_val.isUndef()) { |
| 11782 | 11791 | return sema.addConstUndef(resolved_type); |
| ... | ... | @@ -11786,8 +11795,8 @@ fn analyzeArithmetic( |
| 11786 | 11795 | resolved_type, |
| 11787 | 11796 | try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, target), |
| 11788 | 11797 | ); |
| 11789 | } else break :rs .{ .src = rhs_src, .air_tag = .rem }; | |
| 11790 | } else break :rs .{ .src = lhs_src, .air_tag = .rem }; | |
| 11798 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; | |
| 11799 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; | |
| 11791 | 11800 | }, |
| 11792 | 11801 | .mod => { |
| 11793 | 11802 | // For integers: |
| ... | ... | @@ -11834,6 +11843,7 @@ fn analyzeArithmetic( |
| 11834 | 11843 | return sema.failWithDivideByZero(block, rhs_src); |
| 11835 | 11844 | } |
| 11836 | 11845 | } |
| 11846 | const air_tag: Air.Inst.Tag = if (block.float_mode == .Optimized) .mod_optimized else .mod; | |
| 11837 | 11847 | if (maybe_lhs_val) |lhs_val| { |
| 11838 | 11848 | if (lhs_val.isUndef()) { |
| 11839 | 11849 | return sema.addConstUndef(resolved_type); |
| ... | ... | @@ -11843,8 +11853,8 @@ fn analyzeArithmetic( |
| 11843 | 11853 | resolved_type, |
| 11844 | 11854 | try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, target), |
| 11845 | 11855 | ); |
| 11846 | } else break :rs .{ .src = rhs_src, .air_tag = .mod }; | |
| 11847 | } else break :rs .{ .src = lhs_src, .air_tag = .mod }; | |
| 11856 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; | |
| 11857 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; | |
| 11848 | 11858 | }, |
| 11849 | 11859 | else => unreachable, |
| 11850 | 11860 | } |
| ... | ... | @@ -11874,7 +11884,7 @@ fn analyzeArithmetic( |
| 11874 | 11884 | const ov_bit = try sema.tupleFieldValByIndex(block, src, op_ov, 1, op_ov_tuple_ty); |
| 11875 | 11885 | const any_ov_bit = if (resolved_type.zigTypeTag() == .Vector) |
| 11876 | 11886 | try block.addInst(.{ |
| 11877 | .tag = .reduce, | |
| 11887 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, | |
| 11878 | 11888 | .data = .{ .reduce = .{ |
| 11879 | 11889 | .operand = ov_bit, |
| 11880 | 11890 | .operation = .Or, |
| ... | ... | @@ -11890,13 +11900,17 @@ fn analyzeArithmetic( |
| 11890 | 11900 | } |
| 11891 | 11901 | } |
| 11892 | 11902 | switch (rs.air_tag) { |
| 11893 | .div_float, .div_exact, .div_trunc, .div_floor => { | |
| 11903 | // zig fmt: off | |
| 11904 | .div_float, .div_exact, .div_trunc, .div_floor, .div_float_optimized, | |
| 11905 | .div_exact_optimized, .div_trunc_optimized, .div_floor_optimized | |
| 11906 | // zig fmt: on | |
| 11907 | => if (scalar_tag == .Int or block.float_mode == .Optimized) { | |
| 11894 | 11908 | const ok = if (resolved_type.zigTypeTag() == .Vector) ok: { |
| 11895 | 11909 | const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero); |
| 11896 | 11910 | const zero = try sema.addConstant(sema.typeOf(casted_rhs), zero_val); |
| 11897 | 11911 | const ok = try block.addCmpVector(casted_rhs, zero, .neq, try sema.addType(resolved_type)); |
| 11898 | 11912 | break :ok try block.addInst(.{ |
| 11899 | .tag = .reduce, | |
| 11913 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, | |
| 11900 | 11914 | .data = .{ .reduce = .{ |
| 11901 | 11915 | .operand = ok, |
| 11902 | 11916 | .operation = .And, |
| ... | ... | @@ -11904,17 +11918,17 @@ fn analyzeArithmetic( |
| 11904 | 11918 | }); |
| 11905 | 11919 | } else ok: { |
| 11906 | 11920 | const zero = try sema.addConstant(sema.typeOf(casted_rhs), Value.zero); |
| 11907 | break :ok try block.addBinOp(.cmp_neq, casted_rhs, zero); | |
| 11921 | break :ok try block.addBinOp(if (block.float_mode == .Optimized) .cmp_neq_optimized else .cmp_neq, casted_rhs, zero); | |
| 11908 | 11922 | }; |
| 11909 | 11923 | try sema.addSafetyCheck(block, ok, .divide_by_zero); |
| 11910 | 11924 | }, |
| 11911 | .rem, .mod => { | |
| 11925 | .rem, .mod, .rem_optimized, .mod_optimized => { | |
| 11912 | 11926 | const ok = if (resolved_type.zigTypeTag() == .Vector) ok: { |
| 11913 | 11927 | const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero); |
| 11914 | 11928 | const zero = try sema.addConstant(sema.typeOf(casted_rhs), zero_val); |
| 11915 | 11929 | const ok = try block.addCmpVector(casted_rhs, zero, if (scalar_tag == .Int) .gt else .neq, try sema.addType(resolved_type)); |
| 11916 | 11930 | break :ok try block.addInst(.{ |
| 11917 | .tag = .reduce, | |
| 11931 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, | |
| 11918 | 11932 | .data = .{ .reduce = .{ |
| 11919 | 11933 | .operand = ok, |
| 11920 | 11934 | .operation = .And, |
| ... | ... | @@ -11922,13 +11936,19 @@ fn analyzeArithmetic( |
| 11922 | 11936 | }); |
| 11923 | 11937 | } else ok: { |
| 11924 | 11938 | const zero = try sema.addConstant(sema.typeOf(casted_rhs), Value.zero); |
| 11925 | break :ok try block.addBinOp(if (scalar_tag == .Int) .cmp_gt else .cmp_neq, casted_rhs, zero); | |
| 11939 | const air_tag = if (scalar_tag == .Int) | |
| 11940 | Air.Inst.Tag.cmp_gt | |
| 11941 | else if (block.float_mode == .Optimized) | |
| 11942 | Air.Inst.Tag.cmp_neq_optimized | |
| 11943 | else | |
| 11944 | Air.Inst.Tag.cmp_neq; | |
| 11945 | break :ok try block.addBinOp(air_tag, casted_rhs, zero); | |
| 11926 | 11946 | }; |
| 11927 | 11947 | try sema.addSafetyCheck(block, ok, .remainder_division_zero_negative); |
| 11928 | 11948 | }, |
| 11929 | 11949 | else => {}, |
| 11930 | 11950 | } |
| 11931 | if (rs.air_tag == .div_exact) { | |
| 11951 | if (rs.air_tag == .div_exact or rs.air_tag == .div_exact_optimized) { | |
| 11932 | 11952 | const result = try block.addBinOp(.div_exact, casted_lhs, casted_rhs); |
| 11933 | 11953 | const ok = if (scalar_tag == .Float) ok: { |
| 11934 | 11954 | const floored = try block.addUnOp(.floor, result); |
| ... | ... | @@ -11936,14 +11956,14 @@ fn analyzeArithmetic( |
| 11936 | 11956 | if (resolved_type.zigTypeTag() == .Vector) { |
| 11937 | 11957 | const eql = try block.addCmpVector(result, floored, .eq, try sema.addType(resolved_type)); |
| 11938 | 11958 | break :ok try block.addInst(.{ |
| 11939 | .tag = .reduce, | |
| 11959 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, | |
| 11940 | 11960 | .data = .{ .reduce = .{ |
| 11941 | 11961 | .operand = eql, |
| 11942 | 11962 | .operation = .And, |
| 11943 | 11963 | } }, |
| 11944 | 11964 | }); |
| 11945 | 11965 | } else { |
| 11946 | const is_in_range = try block.addBinOp(.cmp_eq, result, floored); | |
| 11966 | const is_in_range = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, result, floored); | |
| 11947 | 11967 | break :ok is_in_range; |
| 11948 | 11968 | } |
| 11949 | 11969 | } else ok: { |
| ... | ... | @@ -11962,7 +11982,7 @@ fn analyzeArithmetic( |
| 11962 | 11982 | }); |
| 11963 | 11983 | } else { |
| 11964 | 11984 | const zero = try sema.addConstant(sema.typeOf(casted_rhs), Value.zero); |
| 11965 | const is_in_range = try block.addBinOp(.cmp_eq, remainder, zero); | |
| 11985 | const is_in_range = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, remainder, zero); | |
| 11966 | 11986 | break :ok is_in_range; |
| 11967 | 11987 | } |
| 11968 | 11988 | }; |
| ... | ... | @@ -12476,7 +12496,7 @@ fn cmpSelf( |
| 12476 | 12496 | const result_ty_ref = try sema.addType(result_ty); |
| 12477 | 12497 | return block.addCmpVector(casted_lhs, casted_rhs, op, result_ty_ref); |
| 12478 | 12498 | } |
| 12479 | const tag = Air.Inst.Tag.fromCmpOp(op); | |
| 12499 | const tag = Air.Inst.Tag.fromCmpOp(op, block.float_mode == .Optimized); | |
| 12480 | 12500 | return block.addBinOp(tag, casted_lhs, casted_rhs); |
| 12481 | 12501 | } |
| 12482 | 12502 | |
| ... | ... | @@ -15954,12 +15974,12 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 15954 | 15974 | } |
| 15955 | 15975 | |
| 15956 | 15976 | try sema.requireRuntimeBlock(block, inst_data.src(), operand_src); |
| 15957 | const result = try block.addTyOp(.float_to_int, dest_ty, operand); | |
| 15977 | const result = try block.addTyOp(if (block.float_mode == .Optimized) .float_to_int_optimized else .float_to_int, dest_ty, operand); | |
| 15958 | 15978 | if (block.wantSafety()) { |
| 15959 | 15979 | const back = try block.addTyOp(.int_to_float, operand_ty, result); |
| 15960 | 15980 | const diff = try block.addBinOp(.sub, operand, back); |
| 15961 | const ok_pos = try block.addBinOp(.cmp_lt, diff, try sema.addConstant(operand_ty, Value.one)); | |
| 15962 | const ok_neg = try block.addBinOp(.cmp_gt, diff, try sema.addConstant(operand_ty, Value.negative_one)); | |
| 15981 | const ok_pos = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_lt_optimized else .cmp_lt, diff, try sema.addConstant(operand_ty, Value.one)); | |
| 15982 | const ok_neg = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_gt_optimized else .cmp_gt, diff, try sema.addConstant(operand_ty, Value.negative_one)); | |
| 15963 | 15983 | const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg); |
| 15964 | 15984 | try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds); |
| 15965 | 15985 | } |
| ... | ... | @@ -17194,7 +17214,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 17194 | 17214 | |
| 17195 | 17215 | try sema.requireRuntimeBlock(block, inst_data.src(), operand_src); |
| 17196 | 17216 | return block.addInst(.{ |
| 17197 | .tag = .reduce, | |
| 17217 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, | |
| 17198 | 17218 | .data = .{ .reduce = .{ |
| 17199 | 17219 | .operand = operand, |
| 17200 | 17220 | .operation = operation, |
| ... | ... | @@ -24489,7 +24509,7 @@ fn cmpNumeric( |
| 24489 | 24509 | }; |
| 24490 | 24510 | const casted_lhs = try sema.coerce(block, dest_ty, lhs, lhs_src); |
| 24491 | 24511 | const casted_rhs = try sema.coerce(block, dest_ty, rhs, rhs_src); |
| 24492 | return block.addBinOp(Air.Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs); | |
| 24512 | return block.addBinOp(Air.Inst.Tag.fromCmpOp(op, block.float_mode == .Optimized), casted_lhs, casted_rhs); | |
| 24493 | 24513 | } |
| 24494 | 24514 | // For mixed unsigned integer sizes, implicit cast both operands to the larger integer. |
| 24495 | 24515 | // For mixed signed and unsigned integers, implicit cast both operands to a signed |
| ... | ... | @@ -24610,7 +24630,7 @@ fn cmpNumeric( |
| 24610 | 24630 | const casted_lhs = try sema.coerce(block, dest_ty, lhs, lhs_src); |
| 24611 | 24631 | const casted_rhs = try sema.coerce(block, dest_ty, rhs, rhs_src); |
| 24612 | 24632 | |
| 24613 | return block.addBinOp(Air.Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs); | |
| 24633 | return block.addBinOp(Air.Inst.Tag.fromCmpOp(op, block.float_mode == .Optimized), casted_lhs, casted_rhs); | |
| 24614 | 24634 | } |
| 24615 | 24635 | |
| 24616 | 24636 | /// Asserts that lhs and rhs types are both vectors. |
src/arch/aarch64/CodeGen.zig+24| ... | ... | @@ -729,6 +729,30 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 729 | 729 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 730 | 730 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 731 | 731 | |
| 732 | .add_optimized, | |
| 733 | .addwrap_optimized, | |
| 734 | .sub_optimized, | |
| 735 | .subwrap_optimized, | |
| 736 | .mul_optimized, | |
| 737 | .mulwrap_optimized, | |
| 738 | .div_float_optimized, | |
| 739 | .div_trunc_optimized, | |
| 740 | .div_floor_optimized, | |
| 741 | .div_exact_optimized, | |
| 742 | .rem_optimized, | |
| 743 | .mod_optimized, | |
| 744 | .neg_optimized, | |
| 745 | .cmp_lt_optimized, | |
| 746 | .cmp_lte_optimized, | |
| 747 | .cmp_eq_optimized, | |
| 748 | .cmp_gte_optimized, | |
| 749 | .cmp_gt_optimized, | |
| 750 | .cmp_neq_optimized, | |
| 751 | .cmp_vector_optimized, | |
| 752 | .reduce_optimized, | |
| 753 | .float_to_int_optimized, | |
| 754 | => return self.fail("TODO implement optimized float mode", .{}), | |
| 755 | ||
| 732 | 756 | .wasm_memory_size => unreachable, |
| 733 | 757 | .wasm_memory_grow => unreachable, |
| 734 | 758 | // zig fmt: on |
src/arch/arm/CodeGen.zig+24| ... | ... | @@ -744,6 +744,30 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 744 | 744 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 745 | 745 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 746 | 746 | |
| 747 | .add_optimized, | |
| 748 | .addwrap_optimized, | |
| 749 | .sub_optimized, | |
| 750 | .subwrap_optimized, | |
| 751 | .mul_optimized, | |
| 752 | .mulwrap_optimized, | |
| 753 | .div_float_optimized, | |
| 754 | .div_trunc_optimized, | |
| 755 | .div_floor_optimized, | |
| 756 | .div_exact_optimized, | |
| 757 | .rem_optimized, | |
| 758 | .mod_optimized, | |
| 759 | .neg_optimized, | |
| 760 | .cmp_lt_optimized, | |
| 761 | .cmp_lte_optimized, | |
| 762 | .cmp_eq_optimized, | |
| 763 | .cmp_gte_optimized, | |
| 764 | .cmp_gt_optimized, | |
| 765 | .cmp_neq_optimized, | |
| 766 | .cmp_vector_optimized, | |
| 767 | .reduce_optimized, | |
| 768 | .float_to_int_optimized, | |
| 769 | => return self.fail("TODO implement optimized float mode", .{}), | |
| 770 | ||
| 747 | 771 | .wasm_memory_size => unreachable, |
| 748 | 772 | .wasm_memory_grow => unreachable, |
| 749 | 773 | // zig fmt: on |
src/arch/riscv64/CodeGen.zig+24| ... | ... | @@ -669,6 +669,30 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 669 | 669 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 670 | 670 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 671 | 671 | |
| 672 | .add_optimized, | |
| 673 | .addwrap_optimized, | |
| 674 | .sub_optimized, | |
| 675 | .subwrap_optimized, | |
| 676 | .mul_optimized, | |
| 677 | .mulwrap_optimized, | |
| 678 | .div_float_optimized, | |
| 679 | .div_trunc_optimized, | |
| 680 | .div_floor_optimized, | |
| 681 | .div_exact_optimized, | |
| 682 | .rem_optimized, | |
| 683 | .mod_optimized, | |
| 684 | .neg_optimized, | |
| 685 | .cmp_lt_optimized, | |
| 686 | .cmp_lte_optimized, | |
| 687 | .cmp_eq_optimized, | |
| 688 | .cmp_gte_optimized, | |
| 689 | .cmp_gt_optimized, | |
| 690 | .cmp_neq_optimized, | |
| 691 | .cmp_vector_optimized, | |
| 692 | .reduce_optimized, | |
| 693 | .float_to_int_optimized, | |
| 694 | => return self.fail("TODO implement optimized float mode", .{}), | |
| 695 | ||
| 672 | 696 | .wasm_memory_size => unreachable, |
| 673 | 697 | .wasm_memory_grow => unreachable, |
| 674 | 698 | // zig fmt: on |
src/arch/sparc64/CodeGen.zig+24| ... | ... | @@ -681,6 +681,30 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 681 | 681 | .wrap_errunion_payload => @panic("TODO try self.airWrapErrUnionPayload(inst)"), |
| 682 | 682 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 683 | 683 | |
| 684 | .add_optimized, | |
| 685 | .addwrap_optimized, | |
| 686 | .sub_optimized, | |
| 687 | .subwrap_optimized, | |
| 688 | .mul_optimized, | |
| 689 | .mulwrap_optimized, | |
| 690 | .div_float_optimized, | |
| 691 | .div_trunc_optimized, | |
| 692 | .div_floor_optimized, | |
| 693 | .div_exact_optimized, | |
| 694 | .rem_optimized, | |
| 695 | .mod_optimized, | |
| 696 | .neg_optimized, | |
| 697 | .cmp_lt_optimized, | |
| 698 | .cmp_lte_optimized, | |
| 699 | .cmp_eq_optimized, | |
| 700 | .cmp_gte_optimized, | |
| 701 | .cmp_gt_optimized, | |
| 702 | .cmp_neq_optimized, | |
| 703 | .cmp_vector_optimized, | |
| 704 | .reduce_optimized, | |
| 705 | .float_to_int_optimized, | |
| 706 | => @panic("TODO implement optimized float mode"), | |
| 707 | ||
| 684 | 708 | .wasm_memory_size => unreachable, |
| 685 | 709 | .wasm_memory_grow => unreachable, |
| 686 | 710 | // zig fmt: on |
src/arch/wasm/CodeGen.zig+24| ... | ... | @@ -1622,6 +1622,30 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1622 | 1622 | .err_return_trace, |
| 1623 | 1623 | .set_err_return_trace, |
| 1624 | 1624 | => |tag| return self.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}), |
| 1625 | ||
| 1626 | .add_optimized, | |
| 1627 | .addwrap_optimized, | |
| 1628 | .sub_optimized, | |
| 1629 | .subwrap_optimized, | |
| 1630 | .mul_optimized, | |
| 1631 | .mulwrap_optimized, | |
| 1632 | .div_float_optimized, | |
| 1633 | .div_trunc_optimized, | |
| 1634 | .div_floor_optimized, | |
| 1635 | .div_exact_optimized, | |
| 1636 | .rem_optimized, | |
| 1637 | .mod_optimized, | |
| 1638 | .neg_optimized, | |
| 1639 | .cmp_lt_optimized, | |
| 1640 | .cmp_lte_optimized, | |
| 1641 | .cmp_eq_optimized, | |
| 1642 | .cmp_gte_optimized, | |
| 1643 | .cmp_gt_optimized, | |
| 1644 | .cmp_neq_optimized, | |
| 1645 | .cmp_vector_optimized, | |
| 1646 | .reduce_optimized, | |
| 1647 | .float_to_int_optimized, | |
| 1648 | => return self.fail("TODO implement optimized float mode", .{}), | |
| 1625 | 1649 | }; |
| 1626 | 1650 | } |
| 1627 | 1651 |
src/arch/x86_64/CodeGen.zig+24| ... | ... | @@ -751,6 +751,30 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 751 | 751 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 752 | 752 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 753 | 753 | |
| 754 | .add_optimized, | |
| 755 | .addwrap_optimized, | |
| 756 | .sub_optimized, | |
| 757 | .subwrap_optimized, | |
| 758 | .mul_optimized, | |
| 759 | .mulwrap_optimized, | |
| 760 | .div_float_optimized, | |
| 761 | .div_trunc_optimized, | |
| 762 | .div_floor_optimized, | |
| 763 | .div_exact_optimized, | |
| 764 | .rem_optimized, | |
| 765 | .mod_optimized, | |
| 766 | .neg_optimized, | |
| 767 | .cmp_lt_optimized, | |
| 768 | .cmp_lte_optimized, | |
| 769 | .cmp_eq_optimized, | |
| 770 | .cmp_gte_optimized, | |
| 771 | .cmp_gt_optimized, | |
| 772 | .cmp_neq_optimized, | |
| 773 | .cmp_vector_optimized, | |
| 774 | .reduce_optimized, | |
| 775 | .float_to_int_optimized, | |
| 776 | => return self.fail("TODO implement optimized float mode", .{}), | |
| 777 | ||
| 754 | 778 | .wasm_memory_size => unreachable, |
| 755 | 779 | .wasm_memory_grow => unreachable, |
| 756 | 780 | // zig fmt: on |
src/codegen/c.zig+24| ... | ... | @@ -1928,6 +1928,30 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1928 | 1928 | |
| 1929 | 1929 | .wasm_memory_size => try airWasmMemorySize(f, inst), |
| 1930 | 1930 | .wasm_memory_grow => try airWasmMemoryGrow(f, inst), |
| 1931 | ||
| 1932 | .add_optimized, | |
| 1933 | .addwrap_optimized, | |
| 1934 | .sub_optimized, | |
| 1935 | .subwrap_optimized, | |
| 1936 | .mul_optimized, | |
| 1937 | .mulwrap_optimized, | |
| 1938 | .div_float_optimized, | |
| 1939 | .div_trunc_optimized, | |
| 1940 | .div_floor_optimized, | |
| 1941 | .div_exact_optimized, | |
| 1942 | .rem_optimized, | |
| 1943 | .mod_optimized, | |
| 1944 | .neg_optimized, | |
| 1945 | .cmp_lt_optimized, | |
| 1946 | .cmp_lte_optimized, | |
| 1947 | .cmp_eq_optimized, | |
| 1948 | .cmp_gte_optimized, | |
| 1949 | .cmp_gt_optimized, | |
| 1950 | .cmp_neq_optimized, | |
| 1951 | .cmp_vector_optimized, | |
| 1952 | .reduce_optimized, | |
| 1953 | .float_to_int_optimized, | |
| 1954 | => return f.fail("TODO implement optimized float mode", .{}), | |
| 1931 | 1955 | // zig fmt: on |
| 1932 | 1956 | }; |
| 1933 | 1957 | switch (result_value) { |
src/codegen/llvm.zig+95-40| ... | ... | @@ -3984,21 +3984,21 @@ pub const FuncGen = struct { |
| 3984 | 3984 | for (body) |inst, i| { |
| 3985 | 3985 | const opt_value: ?*const llvm.Value = switch (air_tags[inst]) { |
| 3986 | 3986 | // zig fmt: off |
| 3987 | .add => try self.airAdd(inst), | |
| 3988 | .addwrap => try self.airAddWrap(inst), | |
| 3987 | .add => try self.airAdd(inst, false), | |
| 3988 | .addwrap => try self.airAddWrap(inst, false), | |
| 3989 | 3989 | .add_sat => try self.airAddSat(inst), |
| 3990 | .sub => try self.airSub(inst), | |
| 3991 | .subwrap => try self.airSubWrap(inst), | |
| 3990 | .sub => try self.airSub(inst, false), | |
| 3991 | .subwrap => try self.airSubWrap(inst, false), | |
| 3992 | 3992 | .sub_sat => try self.airSubSat(inst), |
| 3993 | .mul => try self.airMul(inst), | |
| 3994 | .mulwrap => try self.airMulWrap(inst), | |
| 3993 | .mul => try self.airMul(inst, false), | |
| 3994 | .mulwrap => try self.airMulWrap(inst, false), | |
| 3995 | 3995 | .mul_sat => try self.airMulSat(inst), |
| 3996 | .div_float => try self.airDivFloat(inst), | |
| 3997 | .div_trunc => try self.airDivTrunc(inst), | |
| 3998 | .div_floor => try self.airDivFloor(inst), | |
| 3999 | .div_exact => try self.airDivExact(inst), | |
| 4000 | .rem => try self.airRem(inst), | |
| 4001 | .mod => try self.airMod(inst), | |
| 3996 | .div_float => try self.airDivFloat(inst, false), | |
| 3997 | .div_trunc => try self.airDivTrunc(inst, false), | |
| 3998 | .div_floor => try self.airDivFloor(inst, false), | |
| 3999 | .div_exact => try self.airDivExact(inst, false), | |
| 4000 | .rem => try self.airRem(inst, false), | |
| 4001 | .mod => try self.airMod(inst, false), | |
| 4002 | 4002 | .ptr_add => try self.airPtrAdd(inst), |
| 4003 | 4003 | .ptr_sub => try self.airPtrSub(inst), |
| 4004 | 4004 | .shl => try self.airShl(inst), |
| ... | ... | @@ -4009,6 +4009,19 @@ pub const FuncGen = struct { |
| 4009 | 4009 | .slice => try self.airSlice(inst), |
| 4010 | 4010 | .mul_add => try self.airMulAdd(inst), |
| 4011 | 4011 | |
| 4012 | .add_optimized => try self.airAdd(inst, true), | |
| 4013 | .addwrap_optimized => try self.airAddWrap(inst, true), | |
| 4014 | .sub_optimized => try self.airSub(inst, true), | |
| 4015 | .subwrap_optimized => try self.airSubWrap(inst, true), | |
| 4016 | .mul_optimized => try self.airMul(inst, true), | |
| 4017 | .mulwrap_optimized => try self.airMulWrap(inst, true), | |
| 4018 | .div_float_optimized => try self.airDivFloat(inst, true), | |
| 4019 | .div_trunc_optimized => try self.airDivTrunc(inst, true), | |
| 4020 | .div_floor_optimized => try self.airDivFloor(inst, true), | |
| 4021 | .div_exact_optimized => try self.airDivExact(inst, true), | |
| 4022 | .rem_optimized => try self.airRem(inst, true), | |
| 4023 | .mod_optimized => try self.airMod(inst, true), | |
| 4024 | ||
| 4012 | 4025 | .add_with_overflow => try self.airOverflow(inst, "llvm.sadd.with.overflow", "llvm.uadd.with.overflow"), |
| 4013 | 4026 | .sub_with_overflow => try self.airOverflow(inst, "llvm.ssub.with.overflow", "llvm.usub.with.overflow"), |
| 4014 | 4027 | .mul_with_overflow => try self.airOverflow(inst, "llvm.smul.with.overflow", "llvm.umul.with.overflow"), |
| ... | ... | @@ -4034,17 +4047,27 @@ pub const FuncGen = struct { |
| 4034 | 4047 | .ceil => try self.airUnaryOp(inst, .ceil), |
| 4035 | 4048 | .round => try self.airUnaryOp(inst, .round), |
| 4036 | 4049 | .trunc_float => try self.airUnaryOp(inst, .trunc), |
| 4037 | .neg => try self.airUnaryOp(inst, .neg), | |
| 4038 | ||
| 4039 | .cmp_eq => try self.airCmp(inst, .eq), | |
| 4040 | .cmp_gt => try self.airCmp(inst, .gt), | |
| 4041 | .cmp_gte => try self.airCmp(inst, .gte), | |
| 4042 | .cmp_lt => try self.airCmp(inst, .lt), | |
| 4043 | .cmp_lte => try self.airCmp(inst, .lte), | |
| 4044 | .cmp_neq => try self.airCmp(inst, .neq), | |
| 4045 | 4050 | |
| 4046 | .cmp_vector => try self.airCmpVector(inst), | |
| 4047 | .cmp_lt_errors_len => try self.airCmpLtErrorsLen(inst), | |
| 4051 | .neg => try self.airNeg(inst, false), | |
| 4052 | .neg_optimized => try self.airNeg(inst, true), | |
| 4053 | ||
| 4054 | .cmp_eq => try self.airCmp(inst, .eq, false), | |
| 4055 | .cmp_gt => try self.airCmp(inst, .gt, false), | |
| 4056 | .cmp_gte => try self.airCmp(inst, .gte, false), | |
| 4057 | .cmp_lt => try self.airCmp(inst, .lt, false), | |
| 4058 | .cmp_lte => try self.airCmp(inst, .lte, false), | |
| 4059 | .cmp_neq => try self.airCmp(inst, .neq, false), | |
| 4060 | ||
| 4061 | .cmp_eq_optimized => try self.airCmp(inst, .eq, true), | |
| 4062 | .cmp_gt_optimized => try self.airCmp(inst, .gt, true), | |
| 4063 | .cmp_gte_optimized => try self.airCmp(inst, .gte, true), | |
| 4064 | .cmp_lt_optimized => try self.airCmp(inst, .lt, true), | |
| 4065 | .cmp_lte_optimized => try self.airCmp(inst, .lte, true), | |
| 4066 | .cmp_neq_optimized => try self.airCmp(inst, .neq, true), | |
| 4067 | ||
| 4068 | .cmp_vector => try self.airCmpVector(inst, false), | |
| 4069 | .cmp_vector_optimized => try self.airCmpVector(inst, true), | |
| 4070 | .cmp_lt_errors_len => try self.airCmpLtErrorsLen(inst), | |
| 4048 | 4071 | |
| 4049 | 4072 | .is_non_null => try self.airIsNonNull(inst, false, .NE), |
| 4050 | 4073 | .is_non_null_ptr => try self.airIsNonNull(inst, true , .NE), |
| ... | ... | @@ -4093,8 +4116,10 @@ pub const FuncGen = struct { |
| 4093 | 4116 | .ptr_slice_ptr_ptr => try self.airPtrSliceFieldPtr(inst, 0), |
| 4094 | 4117 | .ptr_slice_len_ptr => try self.airPtrSliceFieldPtr(inst, 1), |
| 4095 | 4118 | |
| 4119 | .float_to_int => try self.airFloatToInt(inst, false), | |
| 4120 | .float_to_int_optimized => try self.airFloatToInt(inst, true), | |
| 4121 | ||
| 4096 | 4122 | .array_to_slice => try self.airArrayToSlice(inst), |
| 4097 | .float_to_int => try self.airFloatToInt(inst), | |
| 4098 | 4123 | .int_to_float => try self.airIntToFloat(inst), |
| 4099 | 4124 | .cmpxchg_weak => try self.airCmpxchg(inst, true), |
| 4100 | 4125 | .cmpxchg_strong => try self.airCmpxchg(inst, false), |
| ... | ... | @@ -4115,11 +4140,13 @@ pub const FuncGen = struct { |
| 4115 | 4140 | .splat => try self.airSplat(inst), |
| 4116 | 4141 | .select => try self.airSelect(inst), |
| 4117 | 4142 | .shuffle => try self.airShuffle(inst), |
| 4118 | .reduce => try self.airReduce(inst), | |
| 4119 | 4143 | .aggregate_init => try self.airAggregateInit(inst), |
| 4120 | 4144 | .union_init => try self.airUnionInit(inst), |
| 4121 | 4145 | .prefetch => try self.airPrefetch(inst), |
| 4122 | 4146 | |
| 4147 | .reduce => try self.airReduce(inst, false), | |
| 4148 | .reduce_optimized => try self.airReduce(inst, true), | |
| 4149 | ||
| 4123 | 4150 | .atomic_store_unordered => try self.airAtomicStore(inst, .Unordered), |
| 4124 | 4151 | .atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic), |
| 4125 | 4152 | .atomic_store_release => try self.airAtomicStore(inst, .Release), |
| ... | ... | @@ -4485,8 +4512,9 @@ pub const FuncGen = struct { |
| 4485 | 4512 | return null; |
| 4486 | 4513 | } |
| 4487 | 4514 | |
| 4488 | fn airCmp(self: *FuncGen, inst: Air.Inst.Index, op: math.CompareOperator) !?*const llvm.Value { | |
| 4515 | fn airCmp(self: *FuncGen, inst: Air.Inst.Index, op: math.CompareOperator, want_fast_math: bool) !?*const llvm.Value { | |
| 4489 | 4516 | if (self.liveness.isUnused(inst)) return null; |
| 4517 | self.builder.setFastMath(want_fast_math); | |
| 4490 | 4518 | |
| 4491 | 4519 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 4492 | 4520 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -4496,8 +4524,9 @@ pub const FuncGen = struct { |
| 4496 | 4524 | return self.cmp(lhs, rhs, operand_ty, op); |
| 4497 | 4525 | } |
| 4498 | 4526 | |
| 4499 | fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 4527 | fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 4500 | 4528 | if (self.liveness.isUnused(inst)) return null; |
| 4529 | self.builder.setFastMath(want_fast_math); | |
| 4501 | 4530 | |
| 4502 | 4531 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 4503 | 4532 | const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data; |
| ... | ... | @@ -4943,10 +4972,12 @@ pub const FuncGen = struct { |
| 4943 | 4972 | return self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, ""); |
| 4944 | 4973 | } |
| 4945 | 4974 | |
| 4946 | fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 4975 | fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 4947 | 4976 | if (self.liveness.isUnused(inst)) |
| 4948 | 4977 | return null; |
| 4949 | 4978 | |
| 4979 | self.builder.setFastMath(want_fast_math); | |
| 4980 | ||
| 4950 | 4981 | const target = self.dg.module.getTarget(); |
| 4951 | 4982 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 4952 | 4983 | |
| ... | ... | @@ -6095,8 +6126,9 @@ pub const FuncGen = struct { |
| 6095 | 6126 | return self.builder.buildInsertValue(partial, len, 1, ""); |
| 6096 | 6127 | } |
| 6097 | 6128 | |
| 6098 | fn airAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6129 | fn airAdd(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6099 | 6130 | if (self.liveness.isUnused(inst)) return null; |
| 6131 | self.builder.setFastMath(want_fast_math); | |
| 6100 | 6132 | |
| 6101 | 6133 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6102 | 6134 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6109,8 +6141,9 @@ pub const FuncGen = struct { |
| 6109 | 6141 | return self.builder.buildNUWAdd(lhs, rhs, ""); |
| 6110 | 6142 | } |
| 6111 | 6143 | |
| 6112 | fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6144 | fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6113 | 6145 | if (self.liveness.isUnused(inst)) return null; |
| 6146 | self.builder.setFastMath(want_fast_math); | |
| 6114 | 6147 | |
| 6115 | 6148 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6116 | 6149 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6134,8 +6167,9 @@ pub const FuncGen = struct { |
| 6134 | 6167 | return self.builder.buildUAddSat(lhs, rhs, ""); |
| 6135 | 6168 | } |
| 6136 | 6169 | |
| 6137 | fn airSub(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6170 | fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6138 | 6171 | if (self.liveness.isUnused(inst)) return null; |
| 6172 | self.builder.setFastMath(want_fast_math); | |
| 6139 | 6173 | |
| 6140 | 6174 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6141 | 6175 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6148,8 +6182,9 @@ pub const FuncGen = struct { |
| 6148 | 6182 | return self.builder.buildNUWSub(lhs, rhs, ""); |
| 6149 | 6183 | } |
| 6150 | 6184 | |
| 6151 | fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6185 | fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6152 | 6186 | if (self.liveness.isUnused(inst)) return null; |
| 6187 | self.builder.setFastMath(want_fast_math); | |
| 6153 | 6188 | |
| 6154 | 6189 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6155 | 6190 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6172,8 +6207,9 @@ pub const FuncGen = struct { |
| 6172 | 6207 | return self.builder.buildUSubSat(lhs, rhs, ""); |
| 6173 | 6208 | } |
| 6174 | 6209 | |
| 6175 | fn airMul(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6210 | fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6176 | 6211 | if (self.liveness.isUnused(inst)) return null; |
| 6212 | self.builder.setFastMath(want_fast_math); | |
| 6177 | 6213 | |
| 6178 | 6214 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6179 | 6215 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6186,8 +6222,9 @@ pub const FuncGen = struct { |
| 6186 | 6222 | return self.builder.buildNUWMul(lhs, rhs, ""); |
| 6187 | 6223 | } |
| 6188 | 6224 | |
| 6189 | fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6225 | fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6190 | 6226 | if (self.liveness.isUnused(inst)) return null; |
| 6227 | self.builder.setFastMath(want_fast_math); | |
| 6191 | 6228 | |
| 6192 | 6229 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6193 | 6230 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6210,8 +6247,9 @@ pub const FuncGen = struct { |
| 6210 | 6247 | return self.builder.buildUMulFixSat(lhs, rhs, ""); |
| 6211 | 6248 | } |
| 6212 | 6249 | |
| 6213 | fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6250 | fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6214 | 6251 | if (self.liveness.isUnused(inst)) return null; |
| 6252 | self.builder.setFastMath(want_fast_math); | |
| 6215 | 6253 | |
| 6216 | 6254 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6217 | 6255 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6221,8 +6259,9 @@ pub const FuncGen = struct { |
| 6221 | 6259 | return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs }); |
| 6222 | 6260 | } |
| 6223 | 6261 | |
| 6224 | fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6262 | fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6225 | 6263 | if (self.liveness.isUnused(inst)) return null; |
| 6264 | self.builder.setFastMath(want_fast_math); | |
| 6226 | 6265 | |
| 6227 | 6266 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6228 | 6267 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6238,8 +6277,9 @@ pub const FuncGen = struct { |
| 6238 | 6277 | return self.builder.buildUDiv(lhs, rhs, ""); |
| 6239 | 6278 | } |
| 6240 | 6279 | |
| 6241 | fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6280 | fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6242 | 6281 | if (self.liveness.isUnused(inst)) return null; |
| 6282 | self.builder.setFastMath(want_fast_math); | |
| 6243 | 6283 | |
| 6244 | 6284 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6245 | 6285 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6270,8 +6310,9 @@ pub const FuncGen = struct { |
| 6270 | 6310 | return self.builder.buildUDiv(lhs, rhs, ""); |
| 6271 | 6311 | } |
| 6272 | 6312 | |
| 6273 | fn airDivExact(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6313 | fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6274 | 6314 | if (self.liveness.isUnused(inst)) return null; |
| 6315 | self.builder.setFastMath(want_fast_math); | |
| 6275 | 6316 | |
| 6276 | 6317 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6277 | 6318 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6284,8 +6325,9 @@ pub const FuncGen = struct { |
| 6284 | 6325 | return self.builder.buildExactUDiv(lhs, rhs, ""); |
| 6285 | 6326 | } |
| 6286 | 6327 | |
| 6287 | fn airRem(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6328 | fn airRem(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6288 | 6329 | if (self.liveness.isUnused(inst)) return null; |
| 6330 | self.builder.setFastMath(want_fast_math); | |
| 6289 | 6331 | |
| 6290 | 6332 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6291 | 6333 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -6298,8 +6340,9 @@ pub const FuncGen = struct { |
| 6298 | 6340 | return self.builder.buildURem(lhs, rhs, ""); |
| 6299 | 6341 | } |
| 6300 | 6342 | |
| 6301 | fn airMod(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 6343 | fn airMod(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 6302 | 6344 | if (self.liveness.isUnused(inst)) return null; |
| 6345 | self.builder.setFastMath(want_fast_math); | |
| 6303 | 6346 | |
| 6304 | 6347 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 6305 | 6348 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -7613,6 +7656,17 @@ pub const FuncGen = struct { |
| 7613 | 7656 | return self.buildFloatOp(op, operand_ty, 1, .{operand}); |
| 7614 | 7657 | } |
| 7615 | 7658 | |
| 7659 | fn airNeg(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 7660 | if (self.liveness.isUnused(inst)) return null; | |
| 7661 | self.builder.setFastMath(want_fast_math); | |
| 7662 | ||
| 7663 | const un_op = self.air.instructions.items(.data)[inst].un_op; | |
| 7664 | const operand = try self.resolveInst(un_op); | |
| 7665 | const operand_ty = self.air.typeOf(un_op); | |
| 7666 | ||
| 7667 | return self.buildFloatOp(.neg, operand_ty, 1, .{operand}); | |
| 7668 | } | |
| 7669 | ||
| 7616 | 7670 | fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*const llvm.Value { |
| 7617 | 7671 | if (self.liveness.isUnused(inst)) return null; |
| 7618 | 7672 | |
| ... | ... | @@ -7927,8 +7981,9 @@ pub const FuncGen = struct { |
| 7927 | 7981 | return self.builder.buildShuffleVector(a, b, llvm_mask_value, ""); |
| 7928 | 7982 | } |
| 7929 | 7983 | |
| 7930 | fn airReduce(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 7984 | fn airReduce(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | |
| 7931 | 7985 | if (self.liveness.isUnused(inst)) return null; |
| 7986 | self.builder.setFastMath(want_fast_math); | |
| 7932 | 7987 | |
| 7933 | 7988 | const reduce = self.air.instructions.items(.data)[inst].reduce; |
| 7934 | 7989 | const operand = try self.resolveInst(reduce.operand); |
src/codegen/llvm/bindings.zig+3| ... | ... | @@ -941,6 +941,9 @@ pub const Builder = opaque { |
| 941 | 941 | |
| 942 | 942 | pub const buildFPMulReduce = ZigLLVMBuildFPMulReduce; |
| 943 | 943 | extern fn ZigLLVMBuildFPMulReduce(B: *const Builder, Acc: *const Value, Val: *const Value) *const Value; |
| 944 | ||
| 945 | pub const setFastMath = ZigLLVMSetFastMath; | |
| 946 | extern fn ZigLLVMSetFastMath(B: *const Builder, on_state: bool) void; | |
| 944 | 947 | }; |
| 945 | 948 | |
| 946 | 949 | pub const MDString = opaque { |
src/print_air.zig+22-2| ... | ... | @@ -138,6 +138,24 @@ const Writer = struct { |
| 138 | 138 | .set_union_tag, |
| 139 | 139 | .min, |
| 140 | 140 | .max, |
| 141 | .add_optimized, | |
| 142 | .addwrap_optimized, | |
| 143 | .sub_optimized, | |
| 144 | .subwrap_optimized, | |
| 145 | .mul_optimized, | |
| 146 | .mulwrap_optimized, | |
| 147 | .div_float_optimized, | |
| 148 | .div_trunc_optimized, | |
| 149 | .div_floor_optimized, | |
| 150 | .div_exact_optimized, | |
| 151 | .rem_optimized, | |
| 152 | .mod_optimized, | |
| 153 | .cmp_lt_optimized, | |
| 154 | .cmp_lte_optimized, | |
| 155 | .cmp_eq_optimized, | |
| 156 | .cmp_gte_optimized, | |
| 157 | .cmp_gt_optimized, | |
| 158 | .cmp_neq_optimized, | |
| 141 | 159 | => try w.writeBinOp(s, inst), |
| 142 | 160 | |
| 143 | 161 | .is_null, |
| ... | ... | @@ -169,6 +187,7 @@ const Writer = struct { |
| 169 | 187 | .round, |
| 170 | 188 | .trunc_float, |
| 171 | 189 | .neg, |
| 190 | .neg_optimized, | |
| 172 | 191 | .cmp_lt_errors_len, |
| 173 | 192 | .set_err_return_trace, |
| 174 | 193 | => try w.writeUnOp(s, inst), |
| ... | ... | @@ -216,6 +235,7 @@ const Writer = struct { |
| 216 | 235 | .int_to_float, |
| 217 | 236 | .splat, |
| 218 | 237 | .float_to_int, |
| 238 | .float_to_int_optimized, | |
| 219 | 239 | .get_union_tag, |
| 220 | 240 | .clz, |
| 221 | 241 | .ctz, |
| ... | ... | @@ -280,8 +300,8 @@ const Writer = struct { |
| 280 | 300 | .mul_add => try w.writeMulAdd(s, inst), |
| 281 | 301 | .select => try w.writeSelect(s, inst), |
| 282 | 302 | .shuffle => try w.writeShuffle(s, inst), |
| 283 | .reduce => try w.writeReduce(s, inst), | |
| 284 | .cmp_vector => try w.writeCmpVector(s, inst), | |
| 303 | .reduce, .reduce_optimized => try w.writeReduce(s, inst), | |
| 304 | .cmp_vector, .cmp_vector_optimized => try w.writeCmpVector(s, inst), | |
| 285 | 305 | |
| 286 | 306 | .dbg_block_begin, .dbg_block_end => {}, |
| 287 | 307 | } |