| ... | @@ -2105,7 +2105,7 @@ fn zirEnumDecl( | ... | @@ -2105,7 +2105,7 @@ fn zirEnumDecl( |
| 2105 | }); | 2105 | }); |
| 2106 | } else if (any_values) { | 2106 | } else if (any_values) { |
| 2107 | const tag_val = if (last_tag_val) |val| | 2107 | const tag_val = if (last_tag_val) |val| |
| 2108 | try val.intAdd(Value.one, sema.arena) | 2108 | try val.intAdd(Value.one, enum_obj.tag_ty, sema.arena) |
| 2109 | else | 2109 | else |
| 2110 | Value.zero; | 2110 | Value.zero; |
| 2111 | last_tag_val = tag_val; | 2111 | last_tag_val = tag_val; |
| ... | @@ -8192,14 +8192,22 @@ fn zirShl( | ... | @@ -8192,14 +8192,22 @@ fn zirShl( |
| 8192 | defer tracy.end(); | 8192 | defer tracy.end(); |
| 8193 | | 8193 | |
| 8194 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 8194 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| | 8195 | const src = inst_data.src(); |
| 8195 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; | 8196 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 8196 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; | 8197 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 8197 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 8198 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 8198 | const lhs = sema.resolveInst(extra.lhs); | 8199 | const lhs = sema.resolveInst(extra.lhs); |
| 8199 | const rhs = sema.resolveInst(extra.rhs); | 8200 | const rhs = sema.resolveInst(extra.rhs); |
| | 8201 | const lhs_ty = sema.typeOf(lhs); |
| | 8202 | const rhs_ty = sema.typeOf(rhs); |
| | 8203 | const target = sema.mod.getTarget(); |
| | 8204 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| | 8205 | |
| | 8206 | const scalar_ty = lhs_ty.scalarType(); |
| | 8207 | const scalar_rhs_ty = rhs_ty.scalarType(); |
| 8200 | | 8208 | |
| 8201 | // TODO coerce rhs if air_tag is not shl_sat | 8209 | // TODO coerce rhs if air_tag is not shl_sat |
| 8202 | const rhs_is_comptime_int = try sema.checkIntType(block, rhs_src, sema.typeOf(rhs)); | 8210 | const rhs_is_comptime_int = try sema.checkIntType(block, rhs_src, scalar_rhs_ty); |
| 8203 | | 8211 | |
| 8204 | const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs); | 8212 | const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs); |
| 8205 | const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs); | 8213 | const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs); |
| ... | @@ -8213,35 +8221,31 @@ fn zirShl( | ... | @@ -8213,35 +8221,31 @@ fn zirShl( |
| 8213 | } | 8221 | } |
| 8214 | } | 8222 | } |
| 8215 | | 8223 | |
| 8216 | const lhs_ty = sema.typeOf(lhs); | | |
| 8217 | const rhs_ty = sema.typeOf(rhs); | | |
| 8218 | const target = sema.mod.getTarget(); | | |
| 8219 | | | |
| 8220 | const runtime_src = if (maybe_lhs_val) |lhs_val| rs: { | 8224 | const runtime_src = if (maybe_lhs_val) |lhs_val| rs: { |
| 8221 | if (lhs_val.isUndef()) return sema.addConstUndef(lhs_ty); | 8225 | if (lhs_val.isUndef()) return sema.addConstUndef(lhs_ty); |
| 8222 | const rhs_val = maybe_rhs_val orelse break :rs rhs_src; | 8226 | const rhs_val = maybe_rhs_val orelse break :rs rhs_src; |
| 8223 | | 8227 | |
| 8224 | const val = switch (air_tag) { | 8228 | const val = switch (air_tag) { |
| 8225 | .shl_exact => val: { | 8229 | .shl_exact => val: { |
| 8226 | const shifted = try lhs_val.shl(rhs_val, sema.arena); | 8230 | const shifted = try lhs_val.shl(rhs_val, lhs_ty, sema.arena); |
| 8227 | if (lhs_ty.zigTypeTag() == .ComptimeInt) { | 8231 | if (scalar_ty.zigTypeTag() == .ComptimeInt) { |
| 8228 | break :val shifted; | 8232 | break :val shifted; |
| 8229 | } | 8233 | } |
| 8230 | const int_info = lhs_ty.intInfo(target); | 8234 | const int_info = scalar_ty.intInfo(target); |
| 8231 | const truncated = try shifted.intTrunc(sema.arena, int_info.signedness, int_info.bits); | 8235 | const truncated = try shifted.intTrunc(lhs_ty, sema.arena, int_info.signedness, int_info.bits); |
| 8232 | if (truncated.compareHetero(.eq, shifted)) { | 8236 | if (truncated.compare(.eq, shifted, lhs_ty)) { |
| 8233 | break :val shifted; | 8237 | break :val shifted; |
| 8234 | } | 8238 | } |
| 8235 | return sema.addConstUndef(lhs_ty); | 8239 | return sema.addConstUndef(lhs_ty); |
| 8236 | }, | 8240 | }, |
| 8237 | | 8241 | |
| 8238 | .shl_sat => if (lhs_ty.zigTypeTag() == .ComptimeInt) | 8242 | .shl_sat => if (scalar_ty.zigTypeTag() == .ComptimeInt) |
| 8239 | try lhs_val.shl(rhs_val, sema.arena) | 8243 | try lhs_val.shl(rhs_val, lhs_ty, sema.arena) |
| 8240 | else | 8244 | else |
| 8241 | try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, target), | 8245 | try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, target), |
| 8242 | | 8246 | |
| 8243 | .shl => if (lhs_ty.zigTypeTag() == .ComptimeInt) | 8247 | .shl => if (scalar_ty.zigTypeTag() == .ComptimeInt) |
| 8244 | try lhs_val.shl(rhs_val, sema.arena) | 8248 | try lhs_val.shl(rhs_val, lhs_ty, sema.arena) |
| 8245 | else | 8249 | else |
| 8246 | try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, target), | 8250 | try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, target), |
| 8247 | | 8251 | |
| ... | @@ -8256,7 +8260,7 @@ fn zirShl( | ... | @@ -8256,7 +8260,7 @@ fn zirShl( |
| 8256 | const new_rhs = if (air_tag == .shl_sat) rhs: { | 8260 | const new_rhs = if (air_tag == .shl_sat) rhs: { |
| 8257 | // Limit the RHS type for saturating shl to be an integer as small as the LHS. | 8261 | // Limit the RHS type for saturating shl to be an integer as small as the LHS. |
| 8258 | if (rhs_is_comptime_int or | 8262 | if (rhs_is_comptime_int or |
| 8259 | rhs_ty.intInfo(target).bits > lhs_ty.intInfo(target).bits) | 8263 | scalar_rhs_ty.intInfo(target).bits > scalar_ty.intInfo(target).bits) |
| 8260 | { | 8264 | { |
| 8261 | const max_int = try sema.addConstant( | 8265 | const max_int = try sema.addConstant( |
| 8262 | lhs_ty, | 8266 | lhs_ty, |
| ... | @@ -8283,15 +8287,18 @@ fn zirShr( | ... | @@ -8283,15 +8287,18 @@ fn zirShr( |
| 8283 | defer tracy.end(); | 8287 | defer tracy.end(); |
| 8284 | | 8288 | |
| 8285 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 8289 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| | 8290 | const src = inst_data.src(); |
| 8286 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; | 8291 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 8287 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; | 8292 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 8288 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 8293 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 8289 | const lhs = sema.resolveInst(extra.lhs); | 8294 | const lhs = sema.resolveInst(extra.lhs); |
| 8290 | const rhs = sema.resolveInst(extra.rhs); | 8295 | const rhs = sema.resolveInst(extra.rhs); |
| | 8296 | const lhs_ty = sema.typeOf(lhs); |
| | 8297 | const rhs_ty = sema.typeOf(rhs); |
| | 8298 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 8291 | | 8299 | |
| 8292 | const runtime_src = if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| rs: { | 8300 | const runtime_src = if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| rs: { |
| 8293 | if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| { | 8301 | if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| { |
| 8294 | const lhs_ty = sema.typeOf(lhs); | | |
| 8295 | if (lhs_val.isUndef() or rhs_val.isUndef()) { | 8302 | if (lhs_val.isUndef() or rhs_val.isUndef()) { |
| 8296 | return sema.addConstUndef(lhs_ty); | 8303 | return sema.addConstUndef(lhs_ty); |
| 8297 | } | 8304 | } |
| ... | @@ -8301,13 +8308,12 @@ fn zirShr( | ... | @@ -8301,13 +8308,12 @@ fn zirShr( |
| 8301 | } | 8308 | } |
| 8302 | if (air_tag == .shr_exact) { | 8309 | if (air_tag == .shr_exact) { |
| 8303 | // Detect if any ones would be shifted out. | 8310 | // Detect if any ones would be shifted out. |
| 8304 | const bits = @intCast(u16, rhs_val.toUnsignedInt()); | 8311 | const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val); |
| 8305 | const truncated = try lhs_val.intTrunc(sema.arena, .unsigned, bits); | | |
| 8306 | if (!truncated.compareWithZero(.eq)) { | 8312 | if (!truncated.compareWithZero(.eq)) { |
| 8307 | return sema.addConstUndef(lhs_ty); | 8313 | return sema.addConstUndef(lhs_ty); |
| 8308 | } | 8314 | } |
| 8309 | } | 8315 | } |
| 8310 | const val = try lhs_val.shr(rhs_val, sema.arena); | 8316 | const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena); |
| 8311 | return sema.addConstant(lhs_ty, val); | 8317 | return sema.addConstant(lhs_ty, val); |
| 8312 | } else { | 8318 | } else { |
| 8313 | // Even if lhs is not comptime known, we can still deduce certain things based | 8319 | // Even if lhs is not comptime known, we can still deduce certain things based |
| ... | @@ -8342,32 +8348,15 @@ fn zirBitwise( | ... | @@ -8342,32 +8348,15 @@ fn zirBitwise( |
| 8342 | const rhs = sema.resolveInst(extra.rhs); | 8348 | const rhs = sema.resolveInst(extra.rhs); |
| 8343 | const lhs_ty = sema.typeOf(lhs); | 8349 | const lhs_ty = sema.typeOf(lhs); |
| 8344 | const rhs_ty = sema.typeOf(rhs); | 8350 | const rhs_ty = sema.typeOf(rhs); |
| | 8351 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 8345 | | 8352 | |
| 8346 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; | 8353 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 8347 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } }); | 8354 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } }); |
| 8348 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); | 8355 | const scalar_type = resolved_type.scalarType(); |
| 8349 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); | | |
| 8350 | | | |
| 8351 | const scalar_type = if (resolved_type.zigTypeTag() == .Vector) | | |
| 8352 | resolved_type.elemType() | | |
| 8353 | else | | |
| 8354 | resolved_type; | | |
| 8355 | | | |
| 8356 | const scalar_tag = scalar_type.zigTypeTag(); | 8356 | const scalar_tag = scalar_type.zigTypeTag(); |
| 8357 | | 8357 | |
| 8358 | if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) { | 8358 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 8359 | if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) { | 8359 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 8360 | return sema.fail(block, src, "vector length mismatch: {d} and {d}", .{ | | |
| 8361 | lhs_ty.arrayLen(), | | |
| 8362 | rhs_ty.arrayLen(), | | |
| 8363 | }); | | |
| 8364 | } | | |
| 8365 | } else if (lhs_ty.zigTypeTag() == .Vector or rhs_ty.zigTypeTag() == .Vector) { | | |
| 8366 | return sema.fail(block, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{ | | |
| 8367 | lhs_ty, | | |
| 8368 | rhs_ty, | | |
| 8369 | }); | | |
| 8370 | } | | |
| 8371 | | 8360 | |
| 8372 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; | 8361 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 8373 | | 8362 | |
| ... | @@ -8377,16 +8366,13 @@ fn zirBitwise( | ... | @@ -8377,16 +8366,13 @@ fn zirBitwise( |
| 8377 | | 8366 | |
| 8378 | if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| { | 8367 | if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| { |
| 8379 | if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| { | 8368 | if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| { |
| 8380 | if (resolved_type.zigTypeTag() == .Vector) { | | |
| 8381 | return sema.fail(block, src, "TODO implement zirBitwise for vectors at comptime", .{}); | | |
| 8382 | } | | |
| 8383 | const result_val = switch (air_tag) { | 8369 | const result_val = switch (air_tag) { |
| 8384 | .bit_and => try lhs_val.bitwiseAnd(rhs_val, sema.arena), | 8370 | .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena), |
| 8385 | .bit_or => try lhs_val.bitwiseOr(rhs_val, sema.arena), | 8371 | .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena), |
| 8386 | .xor => try lhs_val.bitwiseXor(rhs_val, sema.arena), | 8372 | .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena), |
| 8387 | else => unreachable, | 8373 | else => unreachable, |
| 8388 | }; | 8374 | }; |
| 8389 | return sema.addConstant(scalar_type, result_val); | 8375 | return sema.addConstant(resolved_type, result_val); |
| 8390 | } | 8376 | } |
| 8391 | } | 8377 | } |
| 8392 | | 8378 | |
| ... | @@ -8413,9 +8399,9 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -8413,9 +8399,9 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 8413 | if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { | 8399 | if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { |
| 8414 | const target = sema.mod.getTarget(); | 8400 | const target = sema.mod.getTarget(); |
| 8415 | if (val.isUndef()) { | 8401 | if (val.isUndef()) { |
| 8416 | return sema.addConstUndef(scalar_type); | 8402 | return sema.addConstUndef(operand_type); |
| 8417 | } else if (operand_type.zigTypeTag() == .Vector) { | 8403 | } else if (operand_type.zigTypeTag() == .Vector) { |
| 8418 | const vec_len = try sema.usizeCast(block, operand_src, operand_type.arrayLen()); | 8404 | const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen()); |
| 8419 | var elem_val_buf: Value.ElemValueBuffer = undefined; | 8405 | var elem_val_buf: Value.ElemValueBuffer = undefined; |
| 8420 | const elems = try sema.arena.alloc(Value, vec_len); | 8406 | const elems = try sema.arena.alloc(Value, vec_len); |
| 8421 | for (elems) |*elem, i| { | 8407 | for (elems) |*elem, i| { |
| ... | @@ -8427,8 +8413,8 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -8427,8 +8413,8 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 8427 | try Value.Tag.aggregate.create(sema.arena, elems), | 8413 | try Value.Tag.aggregate.create(sema.arena, elems), |
| 8428 | ); | 8414 | ); |
| 8429 | } else { | 8415 | } else { |
| 8430 | const result_val = try val.bitwiseNot(scalar_type, sema.arena, target); | 8416 | const result_val = try val.bitwiseNot(operand_type, sema.arena, target); |
| 8431 | return sema.addConstant(scalar_type, result_val); | 8417 | return sema.addConstant(operand_type, result_val); |
| 8432 | } | 8418 | } |
| 8433 | } | 8419 | } |
| 8434 | | 8420 | |
| ... | @@ -8780,8 +8766,19 @@ fn zirNegate( | ... | @@ -8780,8 +8766,19 @@ fn zirNegate( |
| 8780 | const src = inst_data.src(); | 8766 | const src = inst_data.src(); |
| 8781 | const lhs_src = src; | 8767 | const lhs_src = src; |
| 8782 | const rhs_src = src; // TODO better source location | 8768 | const rhs_src = src; // TODO better source location |
| 8783 | const lhs = sema.resolveInst(.zero); | 8769 | |
| 8784 | const rhs = sema.resolveInst(inst_data.operand); | 8770 | const rhs = sema.resolveInst(inst_data.operand); |
| | 8771 | const rhs_ty = sema.typeOf(rhs); |
| | 8772 | const rhs_scalar_ty = rhs_ty.scalarType(); |
| | 8773 | |
| | 8774 | if (tag_override == .sub and rhs_scalar_ty.isUnsignedInt()) { |
| | 8775 | return sema.fail(block, src, "negation of type '{}'", .{rhs_ty}); |
| | 8776 | } |
| | 8777 | |
| | 8778 | const lhs = if (rhs_ty.zigTypeTag() == .Vector) |
| | 8779 | try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero)) |
| | 8780 | else |
| | 8781 | sema.resolveInst(.zero); |
| 8785 | | 8782 | |
| 8786 | return sema.analyzeArithmetic(block, tag_override, lhs, rhs, src, lhs_src, rhs_src); | 8783 | return sema.analyzeArithmetic(block, tag_override, lhs, rhs, src, lhs_src, rhs_src); |
| 8787 | } | 8784 | } |
| ... | @@ -8999,18 +8996,8 @@ fn analyzeArithmetic( | ... | @@ -8999,18 +8996,8 @@ fn analyzeArithmetic( |
| 8999 | const rhs_ty = sema.typeOf(rhs); | 8996 | const rhs_ty = sema.typeOf(rhs); |
| 9000 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(); | 8997 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(); |
| 9001 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(); | 8998 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(); |
| 9002 | if (lhs_zig_ty_tag == .Vector and rhs_zig_ty_tag == .Vector) { | 8999 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 9003 | if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) { | 9000 | |
| 9004 | return sema.fail(block, src, "vector length mismatch: {d} and {d}", .{ | | |
| 9005 | lhs_ty.arrayLen(), rhs_ty.arrayLen(), | | |
| 9006 | }); | | |
| 9007 | } | | |
| 9008 | return sema.fail(block, src, "TODO implement support for vectors in Sema.analyzeArithmetic", .{}); | | |
| 9009 | } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) { | | |
| 9010 | return sema.fail(block, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{ | | |
| 9011 | lhs_ty, rhs_ty, | | |
| 9012 | }); | | |
| 9013 | } | | |
| 9014 | if (lhs_zig_ty_tag == .Pointer) switch (lhs_ty.ptrSize()) { | 9001 | if (lhs_zig_ty_tag == .Pointer) switch (lhs_ty.ptrSize()) { |
| 9015 | .One, .Slice => {}, | 9002 | .One, .Slice => {}, |
| 9016 | .Many, .C => { | 9003 | .Many, .C => { |
| ... | @@ -9033,15 +9020,13 @@ fn analyzeArithmetic( | ... | @@ -9033,15 +9020,13 @@ fn analyzeArithmetic( |
| 9033 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ | 9020 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ |
| 9034 | .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, | 9021 | .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, |
| 9035 | }); | 9022 | }); |
| | 9023 | |
| 9036 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); | 9024 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 9037 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); | 9025 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 9038 | | 9026 | |
| 9039 | const scalar_type = if (resolved_type.zigTypeTag() == .Vector) | 9027 | const lhs_scalar_ty = lhs_ty.scalarType(); |
| 9040 | resolved_type.elemType() | 9028 | const rhs_scalar_ty = rhs_ty.scalarType(); |
| 9041 | else | 9029 | const scalar_tag = resolved_type.scalarType().zigTypeTag(); |
| 9042 | resolved_type; | | |
| 9043 | | | |
| 9044 | const scalar_tag = scalar_type.zigTypeTag(); | | |
| 9045 | | 9030 | |
| 9046 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; | 9031 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 9047 | const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat; | 9032 | const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat; |
| ... | @@ -9075,7 +9060,7 @@ fn analyzeArithmetic( | ... | @@ -9075,7 +9060,7 @@ fn analyzeArithmetic( |
| 9075 | if (is_int) { | 9060 | if (is_int) { |
| 9076 | return sema.failWithUseOfUndef(block, rhs_src); | 9061 | return sema.failWithUseOfUndef(block, rhs_src); |
| 9077 | } else { | 9062 | } else { |
| 9078 | return sema.addConstUndef(scalar_type); | 9063 | return sema.addConstUndef(resolved_type); |
| 9079 | } | 9064 | } |
| 9080 | } | 9065 | } |
| 9081 | if (rhs_val.compareWithZero(.eq)) { | 9066 | if (rhs_val.compareWithZero(.eq)) { |
| ... | @@ -9087,19 +9072,19 @@ fn analyzeArithmetic( | ... | @@ -9087,19 +9072,19 @@ fn analyzeArithmetic( |
| 9087 | if (is_int) { | 9072 | if (is_int) { |
| 9088 | return sema.failWithUseOfUndef(block, lhs_src); | 9073 | return sema.failWithUseOfUndef(block, lhs_src); |
| 9089 | } else { | 9074 | } else { |
| 9090 | return sema.addConstUndef(scalar_type); | 9075 | return sema.addConstUndef(resolved_type); |
| 9091 | } | 9076 | } |
| 9092 | } | 9077 | } |
| 9093 | if (maybe_rhs_val) |rhs_val| { | 9078 | if (maybe_rhs_val) |rhs_val| { |
| 9094 | if (is_int) { | 9079 | if (is_int) { |
| 9095 | return sema.addConstant( | 9080 | return sema.addConstant( |
| 9096 | scalar_type, | 9081 | resolved_type, |
| 9097 | try lhs_val.intAdd(rhs_val, sema.arena), | 9082 | try lhs_val.intAdd(rhs_val, resolved_type, sema.arena), |
| 9098 | ); | 9083 | ); |
| 9099 | } else { | 9084 | } else { |
| 9100 | return sema.addConstant( | 9085 | return sema.addConstant( |
| 9101 | scalar_type, | 9086 | resolved_type, |
| 9102 | try lhs_val.floatAdd(rhs_val, scalar_type, sema.arena, target), | 9087 | try lhs_val.floatAdd(rhs_val, resolved_type, sema.arena, target), |
| 9103 | ); | 9088 | ); |
| 9104 | } | 9089 | } |
| 9105 | } else break :rs .{ .src = rhs_src, .air_tag = .add }; | 9090 | } else break :rs .{ .src = rhs_src, .air_tag = .add }; |
| ... | @@ -9116,15 +9101,15 @@ fn analyzeArithmetic( | ... | @@ -9116,15 +9101,15 @@ fn analyzeArithmetic( |
| 9116 | } | 9101 | } |
| 9117 | if (maybe_rhs_val) |rhs_val| { | 9102 | if (maybe_rhs_val) |rhs_val| { |
| 9118 | if (rhs_val.isUndef()) { | 9103 | if (rhs_val.isUndef()) { |
| 9119 | return sema.addConstUndef(scalar_type); | 9104 | return sema.addConstUndef(resolved_type); |
| 9120 | } | 9105 | } |
| 9121 | if (rhs_val.compareWithZero(.eq)) { | 9106 | if (rhs_val.compareWithZero(.eq)) { |
| 9122 | return casted_lhs; | 9107 | return casted_lhs; |
| 9123 | } | 9108 | } |
| 9124 | if (maybe_lhs_val) |lhs_val| { | 9109 | if (maybe_lhs_val) |lhs_val| { |
| 9125 | return sema.addConstant( | 9110 | return sema.addConstant( |
| 9126 | scalar_type, | 9111 | resolved_type, |
| 9127 | try lhs_val.numberAddWrap(rhs_val, scalar_type, sema.arena, target), | 9112 | try lhs_val.numberAddWrap(rhs_val, resolved_type, sema.arena, target), |
| 9128 | ); | 9113 | ); |
| 9129 | } else break :rs .{ .src = lhs_src, .air_tag = .addwrap }; | 9114 | } else break :rs .{ .src = lhs_src, .air_tag = .addwrap }; |
| 9130 | } else break :rs .{ .src = rhs_src, .air_tag = .addwrap }; | 9115 | } else break :rs .{ .src = rhs_src, .air_tag = .addwrap }; |
| ... | @@ -9140,18 +9125,18 @@ fn analyzeArithmetic( | ... | @@ -9140,18 +9125,18 @@ fn analyzeArithmetic( |
| 9140 | } | 9125 | } |
| 9141 | if (maybe_rhs_val) |rhs_val| { | 9126 | if (maybe_rhs_val) |rhs_val| { |
| 9142 | if (rhs_val.isUndef()) { | 9127 | if (rhs_val.isUndef()) { |
| 9143 | return sema.addConstUndef(scalar_type); | 9128 | return sema.addConstUndef(resolved_type); |
| 9144 | } | 9129 | } |
| 9145 | if (rhs_val.compareWithZero(.eq)) { | 9130 | if (rhs_val.compareWithZero(.eq)) { |
| 9146 | return casted_lhs; | 9131 | return casted_lhs; |
| 9147 | } | 9132 | } |
| 9148 | if (maybe_lhs_val) |lhs_val| { | 9133 | if (maybe_lhs_val) |lhs_val| { |
| 9149 | const val = if (scalar_tag == .ComptimeInt) | 9134 | const val = if (scalar_tag == .ComptimeInt) |
| 9150 | try lhs_val.intAdd(rhs_val, sema.arena) | 9135 | try lhs_val.intAdd(rhs_val, resolved_type, sema.arena) |
| 9151 | else | 9136 | else |
| 9152 | try lhs_val.intAddSat(rhs_val, scalar_type, sema.arena, target); | 9137 | try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, target); |
| 9153 | | 9138 | |
| 9154 | return sema.addConstant(scalar_type, val); | 9139 | return sema.addConstant(resolved_type, val); |
| 9155 | } else break :rs .{ .src = lhs_src, .air_tag = .add_sat }; | 9140 | } else break :rs .{ .src = lhs_src, .air_tag = .add_sat }; |
| 9156 | } else break :rs .{ .src = rhs_src, .air_tag = .add_sat }; | 9141 | } else break :rs .{ .src = rhs_src, .air_tag = .add_sat }; |
| 9157 | }, | 9142 | }, |
| ... | @@ -9168,7 +9153,7 @@ fn analyzeArithmetic( | ... | @@ -9168,7 +9153,7 @@ fn analyzeArithmetic( |
| 9168 | if (is_int) { | 9153 | if (is_int) { |
| 9169 | return sema.failWithUseOfUndef(block, rhs_src); | 9154 | return sema.failWithUseOfUndef(block, rhs_src); |
| 9170 | } else { | 9155 | } else { |
| 9171 | return sema.addConstUndef(scalar_type); | 9156 | return sema.addConstUndef(resolved_type); |
| 9172 | } | 9157 | } |
| 9173 | } | 9158 | } |
| 9174 | if (rhs_val.compareWithZero(.eq)) { | 9159 | if (rhs_val.compareWithZero(.eq)) { |
| ... | @@ -9180,19 +9165,19 @@ fn analyzeArithmetic( | ... | @@ -9180,19 +9165,19 @@ fn analyzeArithmetic( |
| 9180 | if (is_int) { | 9165 | if (is_int) { |
| 9181 | return sema.failWithUseOfUndef(block, lhs_src); | 9166 | return sema.failWithUseOfUndef(block, lhs_src); |
| 9182 | } else { | 9167 | } else { |
| 9183 | return sema.addConstUndef(scalar_type); | 9168 | return sema.addConstUndef(resolved_type); |
| 9184 | } | 9169 | } |
| 9185 | } | 9170 | } |
| 9186 | if (maybe_rhs_val) |rhs_val| { | 9171 | if (maybe_rhs_val) |rhs_val| { |
| 9187 | if (is_int) { | 9172 | if (is_int) { |
| 9188 | return sema.addConstant( | 9173 | return sema.addConstant( |
| 9189 | scalar_type, | 9174 | resolved_type, |
| 9190 | try lhs_val.intSub(rhs_val, sema.arena), | 9175 | try lhs_val.intSub(rhs_val, resolved_type, sema.arena), |
| 9191 | ); | 9176 | ); |
| 9192 | } else { | 9177 | } else { |
| 9193 | return sema.addConstant( | 9178 | return sema.addConstant( |
| 9194 | scalar_type, | 9179 | resolved_type, |
| 9195 | try lhs_val.floatSub(rhs_val, scalar_type, sema.arena, target), | 9180 | try lhs_val.floatSub(rhs_val, resolved_type, sema.arena, target), |
| 9196 | ); | 9181 | ); |
| 9197 | } | 9182 | } |
| 9198 | } else break :rs .{ .src = rhs_src, .air_tag = .sub }; | 9183 | } else break :rs .{ .src = rhs_src, .air_tag = .sub }; |
| ... | @@ -9204,7 +9189,7 @@ fn analyzeArithmetic( | ... | @@ -9204,7 +9189,7 @@ fn analyzeArithmetic( |
| 9204 | // If either of the operands are undefined, the result is undefined. | 9189 | // If either of the operands are undefined, the result is undefined. |
| 9205 | if (maybe_rhs_val) |rhs_val| { | 9190 | if (maybe_rhs_val) |rhs_val| { |
| 9206 | if (rhs_val.isUndef()) { | 9191 | if (rhs_val.isUndef()) { |
| 9207 | return sema.addConstUndef(scalar_type); | 9192 | return sema.addConstUndef(resolved_type); |
| 9208 | } | 9193 | } |
| 9209 | if (rhs_val.compareWithZero(.eq)) { | 9194 | if (rhs_val.compareWithZero(.eq)) { |
| 9210 | return casted_lhs; | 9195 | return casted_lhs; |
| ... | @@ -9212,12 +9197,12 @@ fn analyzeArithmetic( | ... | @@ -9212,12 +9197,12 @@ fn analyzeArithmetic( |
| 9212 | } | 9197 | } |
| 9213 | if (maybe_lhs_val) |lhs_val| { | 9198 | if (maybe_lhs_val) |lhs_val| { |
| 9214 | if (lhs_val.isUndef()) { | 9199 | if (lhs_val.isUndef()) { |
| 9215 | return sema.addConstUndef(scalar_type); | 9200 | return sema.addConstUndef(resolved_type); |
| 9216 | } | 9201 | } |
| 9217 | if (maybe_rhs_val) |rhs_val| { | 9202 | if (maybe_rhs_val) |rhs_val| { |
| 9218 | return sema.addConstant( | 9203 | return sema.addConstant( |
| 9219 | scalar_type, | 9204 | resolved_type, |
| 9220 | try lhs_val.numberSubWrap(rhs_val, scalar_type, sema.arena, target), | 9205 | try lhs_val.numberSubWrap(rhs_val, resolved_type, sema.arena, target), |
| 9221 | ); | 9206 | ); |
| 9222 | } else break :rs .{ .src = rhs_src, .air_tag = .subwrap }; | 9207 | } else break :rs .{ .src = rhs_src, .air_tag = .subwrap }; |
| 9223 | } else break :rs .{ .src = lhs_src, .air_tag = .subwrap }; | 9208 | } else break :rs .{ .src = lhs_src, .air_tag = .subwrap }; |
| ... | @@ -9228,7 +9213,7 @@ fn analyzeArithmetic( | ... | @@ -9228,7 +9213,7 @@ fn analyzeArithmetic( |
| 9228 | // If either of the operands are undefined, result is undefined. | 9213 | // If either of the operands are undefined, result is undefined. |
| 9229 | if (maybe_rhs_val) |rhs_val| { | 9214 | if (maybe_rhs_val) |rhs_val| { |
| 9230 | if (rhs_val.isUndef()) { | 9215 | if (rhs_val.isUndef()) { |
| 9231 | return sema.addConstUndef(scalar_type); | 9216 | return sema.addConstUndef(resolved_type); |
| 9232 | } | 9217 | } |
| 9233 | if (rhs_val.compareWithZero(.eq)) { | 9218 | if (rhs_val.compareWithZero(.eq)) { |
| 9234 | return casted_lhs; | 9219 | return casted_lhs; |
| ... | @@ -9236,15 +9221,15 @@ fn analyzeArithmetic( | ... | @@ -9236,15 +9221,15 @@ fn analyzeArithmetic( |
| 9236 | } | 9221 | } |
| 9237 | if (maybe_lhs_val) |lhs_val| { | 9222 | if (maybe_lhs_val) |lhs_val| { |
| 9238 | if (lhs_val.isUndef()) { | 9223 | if (lhs_val.isUndef()) { |
| 9239 | return sema.addConstUndef(scalar_type); | 9224 | return sema.addConstUndef(resolved_type); |
| 9240 | } | 9225 | } |
| 9241 | if (maybe_rhs_val) |rhs_val| { | 9226 | if (maybe_rhs_val) |rhs_val| { |
| 9242 | const val = if (scalar_tag == .ComptimeInt) | 9227 | const val = if (scalar_tag == .ComptimeInt) |
| 9243 | try lhs_val.intSub(rhs_val, sema.arena) | 9228 | try lhs_val.intSub(rhs_val, resolved_type, sema.arena) |
| 9244 | else | 9229 | else |
| 9245 | try lhs_val.intSubSat(rhs_val, scalar_type, sema.arena, target); | 9230 | try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, target); |
| 9246 | | 9231 | |
| 9247 | return sema.addConstant(scalar_type, val); | 9232 | return sema.addConstant(resolved_type, val); |
| 9248 | } else break :rs .{ .src = rhs_src, .air_tag = .sub_sat }; | 9233 | } else break :rs .{ .src = rhs_src, .air_tag = .sub_sat }; |
| 9249 | } else break :rs .{ .src = lhs_src, .air_tag = .sub_sat }; | 9234 | } else break :rs .{ .src = lhs_src, .air_tag = .sub_sat }; |
| 9250 | }, | 9235 | }, |
| ... | @@ -9274,7 +9259,7 @@ fn analyzeArithmetic( | ... | @@ -9274,7 +9259,7 @@ fn analyzeArithmetic( |
| 9274 | if (maybe_lhs_val) |lhs_val| { | 9259 | if (maybe_lhs_val) |lhs_val| { |
| 9275 | if (!lhs_val.isUndef()) { | 9260 | if (!lhs_val.isUndef()) { |
| 9276 | if (lhs_val.compareWithZero(.eq)) { | 9261 | if (lhs_val.compareWithZero(.eq)) { |
| 9277 | return sema.addConstant(scalar_type, Value.zero); | 9262 | return sema.addConstant(resolved_type, Value.zero); |
| 9278 | } | 9263 | } |
| 9279 | } | 9264 | } |
| 9280 | } | 9265 | } |
| ... | @@ -9288,27 +9273,27 @@ fn analyzeArithmetic( | ... | @@ -9288,27 +9273,27 @@ fn analyzeArithmetic( |
| 9288 | } | 9273 | } |
| 9289 | if (maybe_lhs_val) |lhs_val| { | 9274 | if (maybe_lhs_val) |lhs_val| { |
| 9290 | if (lhs_val.isUndef()) { | 9275 | if (lhs_val.isUndef()) { |
| 9291 | if (lhs_ty.isSignedInt() and rhs_ty.isSignedInt()) { | 9276 | if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) { |
| 9292 | if (maybe_rhs_val) |rhs_val| { | 9277 | if (maybe_rhs_val) |rhs_val| { |
| 9293 | if (rhs_val.compare(.neq, Value.negative_one, scalar_type)) { | 9278 | if (rhs_val.compare(.neq, Value.negative_one, rhs_ty)) { |
| 9294 | return sema.addConstUndef(scalar_type); | 9279 | return sema.addConstUndef(resolved_type); |
| 9295 | } | 9280 | } |
| 9296 | } | 9281 | } |
| 9297 | return sema.failWithUseOfUndef(block, rhs_src); | 9282 | return sema.failWithUseOfUndef(block, rhs_src); |
| 9298 | } | 9283 | } |
| 9299 | return sema.addConstUndef(scalar_type); | 9284 | return sema.addConstUndef(resolved_type); |
| 9300 | } | 9285 | } |
| 9301 | | 9286 | |
| 9302 | if (maybe_rhs_val) |rhs_val| { | 9287 | if (maybe_rhs_val) |rhs_val| { |
| 9303 | if (is_int) { | 9288 | if (is_int) { |
| 9304 | return sema.addConstant( | 9289 | return sema.addConstant( |
| 9305 | scalar_type, | 9290 | resolved_type, |
| 9306 | try lhs_val.intDiv(rhs_val, sema.arena), | 9291 | try lhs_val.intDiv(rhs_val, resolved_type, sema.arena), |
| 9307 | ); | 9292 | ); |
| 9308 | } else { | 9293 | } else { |
| 9309 | return sema.addConstant( | 9294 | return sema.addConstant( |
| 9310 | scalar_type, | 9295 | resolved_type, |
| 9311 | try lhs_val.floatDiv(rhs_val, scalar_type, sema.arena, target), | 9296 | try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, target), |
| 9312 | ); | 9297 | ); |
| 9313 | } | 9298 | } |
| 9314 | } else { | 9299 | } else { |
| ... | @@ -9349,7 +9334,7 @@ fn analyzeArithmetic( | ... | @@ -9349,7 +9334,7 @@ fn analyzeArithmetic( |
| 9349 | if (maybe_lhs_val) |lhs_val| { | 9334 | if (maybe_lhs_val) |lhs_val| { |
| 9350 | if (!lhs_val.isUndef()) { | 9335 | if (!lhs_val.isUndef()) { |
| 9351 | if (lhs_val.compareWithZero(.eq)) { | 9336 | if (lhs_val.compareWithZero(.eq)) { |
| 9352 | return sema.addConstant(scalar_type, Value.zero); | 9337 | return sema.addConstant(resolved_type, Value.zero); |
| 9353 | } | 9338 | } |
| 9354 | } | 9339 | } |
| 9355 | } | 9340 | } |
| ... | @@ -9363,27 +9348,27 @@ fn analyzeArithmetic( | ... | @@ -9363,27 +9348,27 @@ fn analyzeArithmetic( |
| 9363 | } | 9348 | } |
| 9364 | if (maybe_lhs_val) |lhs_val| { | 9349 | if (maybe_lhs_val) |lhs_val| { |
| 9365 | if (lhs_val.isUndef()) { | 9350 | if (lhs_val.isUndef()) { |
| 9366 | if (lhs_ty.isSignedInt() and rhs_ty.isSignedInt()) { | 9351 | if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) { |
| 9367 | if (maybe_rhs_val) |rhs_val| { | 9352 | if (maybe_rhs_val) |rhs_val| { |
| 9368 | if (rhs_val.compare(.neq, Value.negative_one, scalar_type)) { | 9353 | if (rhs_val.compare(.neq, Value.negative_one, rhs_ty)) { |
| 9369 | return sema.addConstUndef(scalar_type); | 9354 | return sema.addConstUndef(resolved_type); |
| 9370 | } | 9355 | } |
| 9371 | } | 9356 | } |
| 9372 | return sema.failWithUseOfUndef(block, rhs_src); | 9357 | return sema.failWithUseOfUndef(block, rhs_src); |
| 9373 | } | 9358 | } |
| 9374 | return sema.addConstUndef(scalar_type); | 9359 | return sema.addConstUndef(resolved_type); |
| 9375 | } | 9360 | } |
| 9376 | | 9361 | |
| 9377 | if (maybe_rhs_val) |rhs_val| { | 9362 | if (maybe_rhs_val) |rhs_val| { |
| 9378 | if (is_int) { | 9363 | if (is_int) { |
| 9379 | return sema.addConstant( | 9364 | return sema.addConstant( |
| 9380 | scalar_type, | 9365 | resolved_type, |
| 9381 | try lhs_val.intDiv(rhs_val, sema.arena), | 9366 | try lhs_val.intDiv(rhs_val, resolved_type, sema.arena), |
| 9382 | ); | 9367 | ); |
| 9383 | } else { | 9368 | } else { |
| 9384 | return sema.addConstant( | 9369 | return sema.addConstant( |
| 9385 | scalar_type, | 9370 | resolved_type, |
| 9386 | try lhs_val.floatDivTrunc(rhs_val, scalar_type, sema.arena, target), | 9371 | try lhs_val.floatDivTrunc(rhs_val, resolved_type, sema.arena, target), |
| 9387 | ); | 9372 | ); |
| 9388 | } | 9373 | } |
| 9389 | } else break :rs .{ .src = rhs_src, .air_tag = .div_trunc }; | 9374 | } else break :rs .{ .src = rhs_src, .air_tag = .div_trunc }; |
| ... | @@ -9412,7 +9397,7 @@ fn analyzeArithmetic( | ... | @@ -9412,7 +9397,7 @@ fn analyzeArithmetic( |
| 9412 | if (maybe_lhs_val) |lhs_val| { | 9397 | if (maybe_lhs_val) |lhs_val| { |
| 9413 | if (!lhs_val.isUndef()) { | 9398 | if (!lhs_val.isUndef()) { |
| 9414 | if (lhs_val.compareWithZero(.eq)) { | 9399 | if (lhs_val.compareWithZero(.eq)) { |
| 9415 | return sema.addConstant(scalar_type, Value.zero); | 9400 | return sema.addConstant(resolved_type, Value.zero); |
| 9416 | } | 9401 | } |
| 9417 | } | 9402 | } |
| 9418 | } | 9403 | } |
| ... | @@ -9426,27 +9411,27 @@ fn analyzeArithmetic( | ... | @@ -9426,27 +9411,27 @@ fn analyzeArithmetic( |
| 9426 | } | 9411 | } |
| 9427 | if (maybe_lhs_val) |lhs_val| { | 9412 | if (maybe_lhs_val) |lhs_val| { |
| 9428 | if (lhs_val.isUndef()) { | 9413 | if (lhs_val.isUndef()) { |
| 9429 | if (lhs_ty.isSignedInt() and rhs_ty.isSignedInt()) { | 9414 | if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) { |
| 9430 | if (maybe_rhs_val) |rhs_val| { | 9415 | if (maybe_rhs_val) |rhs_val| { |
| 9431 | if (rhs_val.compare(.neq, Value.negative_one, scalar_type)) { | 9416 | if (rhs_val.compare(.neq, Value.negative_one, rhs_ty)) { |
| 9432 | return sema.addConstUndef(scalar_type); | 9417 | return sema.addConstUndef(resolved_type); |
| 9433 | } | 9418 | } |
| 9434 | } | 9419 | } |
| 9435 | return sema.failWithUseOfUndef(block, rhs_src); | 9420 | return sema.failWithUseOfUndef(block, rhs_src); |
| 9436 | } | 9421 | } |
| 9437 | return sema.addConstUndef(scalar_type); | 9422 | return sema.addConstUndef(resolved_type); |
| 9438 | } | 9423 | } |
| 9439 | | 9424 | |
| 9440 | if (maybe_rhs_val) |rhs_val| { | 9425 | if (maybe_rhs_val) |rhs_val| { |
| 9441 | if (is_int) { | 9426 | if (is_int) { |
| 9442 | return sema.addConstant( | 9427 | return sema.addConstant( |
| 9443 | scalar_type, | 9428 | resolved_type, |
| 9444 | try lhs_val.intDivFloor(rhs_val, sema.arena), | 9429 | try lhs_val.intDivFloor(rhs_val, resolved_type, sema.arena), |
| 9445 | ); | 9430 | ); |
| 9446 | } else { | 9431 | } else { |
| 9447 | return sema.addConstant( | 9432 | return sema.addConstant( |
| 9448 | scalar_type, | 9433 | resolved_type, |
| 9449 | try lhs_val.floatDivFloor(rhs_val, scalar_type, sema.arena, target), | 9434 | try lhs_val.floatDivFloor(rhs_val, resolved_type, sema.arena, target), |
| 9450 | ); | 9435 | ); |
| 9451 | } | 9436 | } |
| 9452 | } else break :rs .{ .src = rhs_src, .air_tag = .div_floor }; | 9437 | } else break :rs .{ .src = rhs_src, .air_tag = .div_floor }; |
| ... | @@ -9474,7 +9459,7 @@ fn analyzeArithmetic( | ... | @@ -9474,7 +9459,7 @@ fn analyzeArithmetic( |
| 9474 | return sema.failWithUseOfUndef(block, rhs_src); | 9459 | return sema.failWithUseOfUndef(block, rhs_src); |
| 9475 | } else { | 9460 | } else { |
| 9476 | if (lhs_val.compareWithZero(.eq)) { | 9461 | if (lhs_val.compareWithZero(.eq)) { |
| 9477 | return sema.addConstant(scalar_type, Value.zero); | 9462 | return sema.addConstant(resolved_type, Value.zero); |
| 9478 | } | 9463 | } |
| 9479 | } | 9464 | } |
| 9480 | } | 9465 | } |
| ... | @@ -9491,14 +9476,14 @@ fn analyzeArithmetic( | ... | @@ -9491,14 +9476,14 @@ fn analyzeArithmetic( |
| 9491 | if (is_int) { | 9476 | if (is_int) { |
| 9492 | // TODO: emit compile error if there is a remainder | 9477 | // TODO: emit compile error if there is a remainder |
| 9493 | return sema.addConstant( | 9478 | return sema.addConstant( |
| 9494 | scalar_type, | 9479 | resolved_type, |
| 9495 | try lhs_val.intDiv(rhs_val, sema.arena), | 9480 | try lhs_val.intDiv(rhs_val, resolved_type, sema.arena), |
| 9496 | ); | 9481 | ); |
| 9497 | } else { | 9482 | } else { |
| 9498 | // TODO: emit compile error if there is a remainder | 9483 | // TODO: emit compile error if there is a remainder |
| 9499 | return sema.addConstant( | 9484 | return sema.addConstant( |
| 9500 | scalar_type, | 9485 | resolved_type, |
| 9501 | try lhs_val.floatDiv(rhs_val, scalar_type, sema.arena, target), | 9486 | try lhs_val.floatDiv(rhs_val, resolved_type, sema.arena, target), |
| 9502 | ); | 9487 | ); |
| 9503 | } | 9488 | } |
| 9504 | } else break :rs .{ .src = rhs_src, .air_tag = .div_exact }; | 9489 | } else break :rs .{ .src = rhs_src, .air_tag = .div_exact }; |
| ... | @@ -9516,9 +9501,9 @@ fn analyzeArithmetic( | ... | @@ -9516,9 +9501,9 @@ fn analyzeArithmetic( |
| 9516 | if (maybe_lhs_val) |lhs_val| { | 9501 | if (maybe_lhs_val) |lhs_val| { |
| 9517 | if (!lhs_val.isUndef()) { | 9502 | if (!lhs_val.isUndef()) { |
| 9518 | if (lhs_val.compareWithZero(.eq)) { | 9503 | if (lhs_val.compareWithZero(.eq)) { |
| 9519 | return sema.addConstant(scalar_type, Value.zero); | 9504 | return sema.addConstant(resolved_type, Value.zero); |
| 9520 | } | 9505 | } |
| 9521 | if (lhs_val.compare(.eq, Value.one, scalar_type)) { | 9506 | if (lhs_val.compare(.eq, Value.one, lhs_ty)) { |
| 9522 | return casted_rhs; | 9507 | return casted_rhs; |
| 9523 | } | 9508 | } |
| 9524 | } | 9509 | } |
| ... | @@ -9528,13 +9513,13 @@ fn analyzeArithmetic( | ... | @@ -9528,13 +9513,13 @@ fn analyzeArithmetic( |
| 9528 | if (is_int) { | 9513 | if (is_int) { |
| 9529 | return sema.failWithUseOfUndef(block, rhs_src); | 9514 | return sema.failWithUseOfUndef(block, rhs_src); |
| 9530 | } else { | 9515 | } else { |
| 9531 | return sema.addConstUndef(scalar_type); | 9516 | return sema.addConstUndef(resolved_type); |
| 9532 | } | 9517 | } |
| 9533 | } | 9518 | } |
| 9534 | if (rhs_val.compareWithZero(.eq)) { | 9519 | if (rhs_val.compareWithZero(.eq)) { |
| 9535 | return sema.addConstant(scalar_type, Value.zero); | 9520 | return sema.addConstant(resolved_type, Value.zero); |
| 9536 | } | 9521 | } |
| 9537 | if (rhs_val.compare(.eq, Value.one, scalar_type)) { | 9522 | if (rhs_val.compare(.eq, Value.one, rhs_ty)) { |
| 9538 | return casted_lhs; | 9523 | return casted_lhs; |
| 9539 | } | 9524 | } |
| 9540 | if (maybe_lhs_val) |lhs_val| { | 9525 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -9542,18 +9527,18 @@ fn analyzeArithmetic( | ... | @@ -9542,18 +9527,18 @@ fn analyzeArithmetic( |
| 9542 | if (is_int) { | 9527 | if (is_int) { |
| 9543 | return sema.failWithUseOfUndef(block, lhs_src); | 9528 | return sema.failWithUseOfUndef(block, lhs_src); |
| 9544 | } else { | 9529 | } else { |
| 9545 | return sema.addConstUndef(scalar_type); | 9530 | return sema.addConstUndef(resolved_type); |
| 9546 | } | 9531 | } |
| 9547 | } | 9532 | } |
| 9548 | if (is_int) { | 9533 | if (is_int) { |
| 9549 | return sema.addConstant( | 9534 | return sema.addConstant( |
| 9550 | scalar_type, | 9535 | resolved_type, |
| 9551 | try lhs_val.intMul(rhs_val, sema.arena), | 9536 | try lhs_val.intMul(rhs_val, resolved_type, sema.arena), |
| 9552 | ); | 9537 | ); |
| 9553 | } else { | 9538 | } else { |
| 9554 | return sema.addConstant( | 9539 | return sema.addConstant( |
| 9555 | scalar_type, | 9540 | resolved_type, |
| 9556 | try lhs_val.floatMul(rhs_val, scalar_type, sema.arena, target), | 9541 | try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, target), |
| 9557 | ); | 9542 | ); |
| 9558 | } | 9543 | } |
| 9559 | } else break :rs .{ .src = lhs_src, .air_tag = .mul }; | 9544 | } else break :rs .{ .src = lhs_src, .air_tag = .mul }; |
| ... | @@ -9567,30 +9552,30 @@ fn analyzeArithmetic( | ... | @@ -9567,30 +9552,30 @@ fn analyzeArithmetic( |
| 9567 | if (maybe_lhs_val) |lhs_val| { | 9552 | if (maybe_lhs_val) |lhs_val| { |
| 9568 | if (!lhs_val.isUndef()) { | 9553 | if (!lhs_val.isUndef()) { |
| 9569 | if (lhs_val.compareWithZero(.eq)) { | 9554 | if (lhs_val.compareWithZero(.eq)) { |
| 9570 | return sema.addConstant(scalar_type, Value.zero); | 9555 | return sema.addConstant(resolved_type, Value.zero); |
| 9571 | } | 9556 | } |
| 9572 | if (lhs_val.compare(.eq, Value.one, scalar_type)) { | 9557 | if (lhs_val.compare(.eq, Value.one, lhs_ty)) { |
| 9573 | return casted_rhs; | 9558 | return casted_rhs; |
| 9574 | } | 9559 | } |
| 9575 | } | 9560 | } |
| 9576 | } | 9561 | } |
| 9577 | if (maybe_rhs_val) |rhs_val| { | 9562 | if (maybe_rhs_val) |rhs_val| { |
| 9578 | if (rhs_val.isUndef()) { | 9563 | if (rhs_val.isUndef()) { |
| 9579 | return sema.addConstUndef(scalar_type); | 9564 | return sema.addConstUndef(resolved_type); |
| 9580 | } | 9565 | } |
| 9581 | if (rhs_val.compareWithZero(.eq)) { | 9566 | if (rhs_val.compareWithZero(.eq)) { |
| 9582 | return sema.addConstant(scalar_type, Value.zero); | 9567 | return sema.addConstant(resolved_type, Value.zero); |
| 9583 | } | 9568 | } |
| 9584 | if (rhs_val.compare(.eq, Value.one, scalar_type)) { | 9569 | if (rhs_val.compare(.eq, Value.one, rhs_ty)) { |
| 9585 | return casted_lhs; | 9570 | return casted_lhs; |
| 9586 | } | 9571 | } |
| 9587 | if (maybe_lhs_val) |lhs_val| { | 9572 | if (maybe_lhs_val) |lhs_val| { |
| 9588 | if (lhs_val.isUndef()) { | 9573 | if (lhs_val.isUndef()) { |
| 9589 | return sema.addConstUndef(scalar_type); | 9574 | return sema.addConstUndef(resolved_type); |
| 9590 | } | 9575 | } |
| 9591 | return sema.addConstant( | 9576 | return sema.addConstant( |
| 9592 | scalar_type, | 9577 | resolved_type, |
| 9593 | try lhs_val.numberMulWrap(rhs_val, scalar_type, sema.arena, target), | 9578 | try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, target), |
| 9594 | ); | 9579 | ); |
| 9595 | } else break :rs .{ .src = lhs_src, .air_tag = .mulwrap }; | 9580 | } else break :rs .{ .src = lhs_src, .air_tag = .mulwrap }; |
| 9596 | } else break :rs .{ .src = rhs_src, .air_tag = .mulwrap }; | 9581 | } else break :rs .{ .src = rhs_src, .air_tag = .mulwrap }; |
| ... | @@ -9603,34 +9588,34 @@ fn analyzeArithmetic( | ... | @@ -9603,34 +9588,34 @@ fn analyzeArithmetic( |
| 9603 | if (maybe_lhs_val) |lhs_val| { | 9588 | if (maybe_lhs_val) |lhs_val| { |
| 9604 | if (!lhs_val.isUndef()) { | 9589 | if (!lhs_val.isUndef()) { |
| 9605 | if (lhs_val.compareWithZero(.eq)) { | 9590 | if (lhs_val.compareWithZero(.eq)) { |
| 9606 | return sema.addConstant(scalar_type, Value.zero); | 9591 | return sema.addConstant(resolved_type, Value.zero); |
| 9607 | } | 9592 | } |
| 9608 | if (lhs_val.compare(.eq, Value.one, scalar_type)) { | 9593 | if (lhs_val.compare(.eq, Value.one, lhs_ty)) { |
| 9609 | return casted_rhs; | 9594 | return casted_rhs; |
| 9610 | } | 9595 | } |
| 9611 | } | 9596 | } |
| 9612 | } | 9597 | } |
| 9613 | if (maybe_rhs_val) |rhs_val| { | 9598 | if (maybe_rhs_val) |rhs_val| { |
| 9614 | if (rhs_val.isUndef()) { | 9599 | if (rhs_val.isUndef()) { |
| 9615 | return sema.addConstUndef(scalar_type); | 9600 | return sema.addConstUndef(resolved_type); |
| 9616 | } | 9601 | } |
| 9617 | if (rhs_val.compareWithZero(.eq)) { | 9602 | if (rhs_val.compareWithZero(.eq)) { |
| 9618 | return sema.addConstant(scalar_type, Value.zero); | 9603 | return sema.addConstant(resolved_type, Value.zero); |
| 9619 | } | 9604 | } |
| 9620 | if (rhs_val.compare(.eq, Value.one, scalar_type)) { | 9605 | if (rhs_val.compare(.eq, Value.one, rhs_ty)) { |
| 9621 | return casted_lhs; | 9606 | return casted_lhs; |
| 9622 | } | 9607 | } |
| 9623 | if (maybe_lhs_val) |lhs_val| { | 9608 | if (maybe_lhs_val) |lhs_val| { |
| 9624 | if (lhs_val.isUndef()) { | 9609 | if (lhs_val.isUndef()) { |
| 9625 | return sema.addConstUndef(scalar_type); | 9610 | return sema.addConstUndef(resolved_type); |
| 9626 | } | 9611 | } |
| 9627 | | 9612 | |
| 9628 | const val = if (scalar_tag == .ComptimeInt) | 9613 | const val = if (scalar_tag == .ComptimeInt) |
| 9629 | try lhs_val.intMul(rhs_val, sema.arena) | 9614 | try lhs_val.intMul(rhs_val, resolved_type, sema.arena) |
| 9630 | else | 9615 | else |
| 9631 | try lhs_val.intMulSat(rhs_val, scalar_type, sema.arena, target); | 9616 | try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, target); |
| 9632 | | 9617 | |
| 9633 | return sema.addConstant(scalar_type, val); | 9618 | return sema.addConstant(resolved_type, val); |
| 9634 | } else break :rs .{ .src = lhs_src, .air_tag = .mul_sat }; | 9619 | } else break :rs .{ .src = lhs_src, .air_tag = .mul_sat }; |
| 9635 | } else break :rs .{ .src = rhs_src, .air_tag = .mul_sat }; | 9620 | } else break :rs .{ .src = rhs_src, .air_tag = .mul_sat }; |
| 9636 | }, | 9621 | }, |
| ... | @@ -9654,9 +9639,9 @@ fn analyzeArithmetic( | ... | @@ -9654,9 +9639,9 @@ fn analyzeArithmetic( |
| 9654 | return sema.failWithUseOfUndef(block, lhs_src); | 9639 | return sema.failWithUseOfUndef(block, lhs_src); |
| 9655 | } | 9640 | } |
| 9656 | if (lhs_val.compareWithZero(.eq)) { | 9641 | if (lhs_val.compareWithZero(.eq)) { |
| 9657 | return sema.addConstant(scalar_type, Value.zero); | 9642 | return sema.addConstant(resolved_type, Value.zero); |
| 9658 | } | 9643 | } |
| 9659 | } else if (lhs_ty.isSignedInt()) { | 9644 | } else if (lhs_scalar_ty.isSignedInt()) { |
| 9660 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); | 9645 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); |
| 9661 | } | 9646 | } |
| 9662 | if (maybe_rhs_val) |rhs_val| { | 9647 | if (maybe_rhs_val) |rhs_val| { |
| ... | @@ -9667,7 +9652,7 @@ fn analyzeArithmetic( | ... | @@ -9667,7 +9652,7 @@ fn analyzeArithmetic( |
| 9667 | return sema.failWithDivideByZero(block, rhs_src); | 9652 | return sema.failWithDivideByZero(block, rhs_src); |
| 9668 | } | 9653 | } |
| 9669 | if (maybe_lhs_val) |lhs_val| { | 9654 | if (maybe_lhs_val) |lhs_val| { |
| 9670 | const rem_result = try lhs_val.intRem(rhs_val, sema.arena); | 9655 | const rem_result = try lhs_val.intRem(rhs_val, resolved_type, sema.arena); |
| 9671 | // If this answer could possibly be different by doing `intMod`, | 9656 | // If this answer could possibly be different by doing `intMod`, |
| 9672 | // we must emit a compile error. Otherwise, it's OK. | 9657 | // we must emit a compile error. Otherwise, it's OK. |
| 9673 | if (rhs_val.compareWithZero(.lt) != lhs_val.compareWithZero(.lt) and | 9658 | if (rhs_val.compareWithZero(.lt) != lhs_val.compareWithZero(.lt) and |
| ... | @@ -9681,12 +9666,12 @@ fn analyzeArithmetic( | ... | @@ -9681,12 +9666,12 @@ fn analyzeArithmetic( |
| 9681 | } | 9666 | } |
| 9682 | if (lhs_val.compareWithZero(.lt)) { | 9667 | if (lhs_val.compareWithZero(.lt)) { |
| 9683 | // Negative | 9668 | // Negative |
| 9684 | return sema.addConstant(scalar_type, Value.zero); | 9669 | return sema.addConstant(resolved_type, Value.zero); |
| 9685 | } | 9670 | } |
| 9686 | return sema.addConstant(scalar_type, rem_result); | 9671 | return sema.addConstant(resolved_type, rem_result); |
| 9687 | } | 9672 | } |
| 9688 | break :rs .{ .src = lhs_src, .air_tag = .rem }; | 9673 | break :rs .{ .src = lhs_src, .air_tag = .rem }; |
| 9689 | } else if (rhs_ty.isSignedInt()) { | 9674 | } else if (rhs_scalar_ty.isSignedInt()) { |
| 9690 | return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty); | 9675 | return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty); |
| 9691 | } else { | 9676 | } else { |
| 9692 | break :rs .{ .src = rhs_src, .air_tag = .rem }; | 9677 | break :rs .{ .src = rhs_src, .air_tag = .rem }; |
| ... | @@ -9708,8 +9693,8 @@ fn analyzeArithmetic( | ... | @@ -9708,8 +9693,8 @@ fn analyzeArithmetic( |
| 9708 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); | 9693 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); |
| 9709 | } | 9694 | } |
| 9710 | return sema.addConstant( | 9695 | return sema.addConstant( |
| 9711 | scalar_type, | 9696 | resolved_type, |
| 9712 | try lhs_val.floatRem(rhs_val, scalar_type, sema.arena, target), | 9697 | try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, target), |
| 9713 | ); | 9698 | ); |
| 9714 | } else { | 9699 | } else { |
| 9715 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); | 9700 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); |
| ... | @@ -9745,8 +9730,8 @@ fn analyzeArithmetic( | ... | @@ -9745,8 +9730,8 @@ fn analyzeArithmetic( |
| 9745 | } | 9730 | } |
| 9746 | if (maybe_lhs_val) |lhs_val| { | 9731 | if (maybe_lhs_val) |lhs_val| { |
| 9747 | return sema.addConstant( | 9732 | return sema.addConstant( |
| 9748 | scalar_type, | 9733 | resolved_type, |
| 9749 | try lhs_val.intRem(rhs_val, sema.arena), | 9734 | try lhs_val.intRem(rhs_val, resolved_type, sema.arena), |
| 9750 | ); | 9735 | ); |
| 9751 | } | 9736 | } |
| 9752 | break :rs .{ .src = lhs_src, .air_tag = .rem }; | 9737 | break :rs .{ .src = lhs_src, .air_tag = .rem }; |
| ... | @@ -9765,12 +9750,12 @@ fn analyzeArithmetic( | ... | @@ -9765,12 +9750,12 @@ fn analyzeArithmetic( |
| 9765 | } | 9750 | } |
| 9766 | if (maybe_lhs_val) |lhs_val| { | 9751 | if (maybe_lhs_val) |lhs_val| { |
| 9767 | if (lhs_val.isUndef()) { | 9752 | if (lhs_val.isUndef()) { |
| 9768 | return sema.addConstUndef(scalar_type); | 9753 | return sema.addConstUndef(resolved_type); |
| 9769 | } | 9754 | } |
| 9770 | if (maybe_rhs_val) |rhs_val| { | 9755 | if (maybe_rhs_val) |rhs_val| { |
| 9771 | return sema.addConstant( | 9756 | return sema.addConstant( |
| 9772 | scalar_type, | 9757 | resolved_type, |
| 9773 | try lhs_val.floatRem(rhs_val, scalar_type, sema.arena, target), | 9758 | try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, target), |
| 9774 | ); | 9759 | ); |
| 9775 | } else break :rs .{ .src = rhs_src, .air_tag = .rem }; | 9760 | } else break :rs .{ .src = rhs_src, .air_tag = .rem }; |
| 9776 | } else break :rs .{ .src = lhs_src, .air_tag = .rem }; | 9761 | } else break :rs .{ .src = lhs_src, .air_tag = .rem }; |
| ... | @@ -9802,8 +9787,8 @@ fn analyzeArithmetic( | ... | @@ -9802,8 +9787,8 @@ fn analyzeArithmetic( |
| 9802 | } | 9787 | } |
| 9803 | if (maybe_lhs_val) |lhs_val| { | 9788 | if (maybe_lhs_val) |lhs_val| { |
| 9804 | return sema.addConstant( | 9789 | return sema.addConstant( |
| 9805 | scalar_type, | 9790 | resolved_type, |
| 9806 | try lhs_val.intMod(rhs_val, sema.arena), | 9791 | try lhs_val.intMod(rhs_val, resolved_type, sema.arena), |
| 9807 | ); | 9792 | ); |
| 9808 | } | 9793 | } |
| 9809 | break :rs .{ .src = lhs_src, .air_tag = .mod }; | 9794 | break :rs .{ .src = lhs_src, .air_tag = .mod }; |
| ... | @@ -9822,12 +9807,12 @@ fn analyzeArithmetic( | ... | @@ -9822,12 +9807,12 @@ fn analyzeArithmetic( |
| 9822 | } | 9807 | } |
| 9823 | if (maybe_lhs_val) |lhs_val| { | 9808 | if (maybe_lhs_val) |lhs_val| { |
| 9824 | if (lhs_val.isUndef()) { | 9809 | if (lhs_val.isUndef()) { |
| 9825 | return sema.addConstUndef(scalar_type); | 9810 | return sema.addConstUndef(resolved_type); |
| 9826 | } | 9811 | } |
| 9827 | if (maybe_rhs_val) |rhs_val| { | 9812 | if (maybe_rhs_val) |rhs_val| { |
| 9828 | return sema.addConstant( | 9813 | return sema.addConstant( |
| 9829 | scalar_type, | 9814 | resolved_type, |
| 9830 | try lhs_val.floatMod(rhs_val, scalar_type, sema.arena, target), | 9815 | try lhs_val.floatMod(rhs_val, resolved_type, sema.arena, target), |
| 9831 | ); | 9816 | ); |
| 9832 | } else break :rs .{ .src = rhs_src, .air_tag = .mod }; | 9817 | } else break :rs .{ .src = rhs_src, .air_tag = .mod }; |
| 9833 | } else break :rs .{ .src = lhs_src, .air_tag = .mod }; | 9818 | } else break :rs .{ .src = lhs_src, .air_tag = .mod }; |
| ... | @@ -10178,6 +10163,11 @@ fn analyzeCmp( | ... | @@ -10178,6 +10163,11 @@ fn analyzeCmp( |
| 10178 | ) CompileError!Air.Inst.Ref { | 10163 | ) CompileError!Air.Inst.Ref { |
| 10179 | const lhs_ty = sema.typeOf(lhs); | 10164 | const lhs_ty = sema.typeOf(lhs); |
| 10180 | const rhs_ty = sema.typeOf(rhs); | 10165 | const rhs_ty = sema.typeOf(rhs); |
| | 10166 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| | 10167 | |
| | 10168 | if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) { |
| | 10169 | return sema.cmpVector(block, src, lhs, rhs, op, lhs_src, rhs_src); |
| | 10170 | } |
| 10181 | if (lhs_ty.isNumeric() and rhs_ty.isNumeric()) { | 10171 | if (lhs_ty.isNumeric() and rhs_ty.isNumeric()) { |
| 10182 | // This operation allows any combination of integer and float types, regardless of the | 10172 | // This operation allows any combination of integer and float types, regardless of the |
| 10183 | // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for | 10173 | // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for |
| ... | @@ -10212,6 +10202,12 @@ fn cmpSelf( | ... | @@ -10212,6 +10202,12 @@ fn cmpSelf( |
| 10212 | if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| { | 10202 | if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| { |
| 10213 | if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool); | 10203 | if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool); |
| 10214 | | 10204 | |
| | 10205 | if (resolved_type.zigTypeTag() == .Vector) { |
| | 10206 | const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool"); |
| | 10207 | const cmp_val = try lhs_val.compareVector(op, rhs_val, resolved_type, sema.arena); |
| | 10208 | return sema.addConstant(result_ty, cmp_val); |
| | 10209 | } |
| | 10210 | |
| 10215 | if (lhs_val.compare(op, rhs_val, resolved_type)) { | 10211 | if (lhs_val.compare(op, rhs_val, resolved_type)) { |
| 10216 | return Air.Inst.Ref.bool_true; | 10212 | return Air.Inst.Ref.bool_true; |
| 10217 | } else { | 10213 | } else { |
| ... | @@ -10237,16 +10233,12 @@ fn cmpSelf( | ... | @@ -10237,16 +10233,12 @@ fn cmpSelf( |
| 10237 | } | 10233 | } |
| 10238 | }; | 10234 | }; |
| 10239 | try sema.requireRuntimeBlock(block, runtime_src); | 10235 | try sema.requireRuntimeBlock(block, runtime_src); |
| 10240 | | 10236 | if (resolved_type.zigTypeTag() == .Vector) { |
| 10241 | const tag: Air.Inst.Tag = switch (op) { | 10237 | const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool"); |
| 10242 | .lt => .cmp_lt, | 10238 | const result_ty_ref = try sema.addType(result_ty); |
| 10243 | .lte => .cmp_lte, | 10239 | return block.addCmpVector(casted_lhs, casted_rhs, op, result_ty_ref); |
| 10244 | .eq => .cmp_eq, | 10240 | } |
| 10245 | .gte => .cmp_gte, | 10241 | const tag = Air.Inst.Tag.fromCmpOp(op); |
| 10246 | .gt => .cmp_gt, | | |
| 10247 | .neq => .cmp_neq, | | |
| 10248 | }; | | |
| 10249 | // TODO handle vectors | | |
| 10250 | return block.addBinOp(tag, casted_lhs, casted_rhs); | 10242 | return block.addBinOp(tag, casted_lhs, casted_rhs); |
| 10251 | } | 10243 | } |
| 10252 | | 10244 | |
| ... | @@ -11367,7 +11359,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi | ... | @@ -11367,7 +11359,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi |
| 11367 | const elem_ty = operand.elemType2(); | 11359 | const elem_ty = operand.elemType2(); |
| 11368 | const log2_elem_ty = try sema.log2IntType(block, elem_ty, src); | 11360 | const log2_elem_ty = try sema.log2IntType(block, elem_ty, src); |
| 11369 | return Type.Tag.vector.create(sema.arena, .{ | 11361 | return Type.Tag.vector.create(sema.arena, .{ |
| 11370 | .len = operand.arrayLen(), | 11362 | .len = operand.vectorLen(), |
| 11371 | .elem_type = log2_elem_ty, | 11363 | .elem_type = log2_elem_ty, |
| 11372 | }); | 11364 | }); |
| 11373 | }, | 11365 | }, |
| ... | @@ -13298,7 +13290,7 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -13298,7 +13290,7 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 13298 | | 13290 | |
| 13299 | if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { | 13291 | if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { |
| 13300 | const target = sema.mod.getTarget(); | 13292 | const target = sema.mod.getTarget(); |
| 13301 | const result_val = val.floatToInt(sema.arena, dest_ty, target) catch |err| switch (err) { | 13293 | const result_val = val.floatToInt(sema.arena, operand_ty, dest_ty, target) catch |err| switch (err) { |
| 13302 | error.FloatCannotFit => { | 13294 | error.FloatCannotFit => { |
| 13303 | return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty }); | 13295 | return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty }); |
| 13304 | }, | 13296 | }, |
| ... | @@ -13325,7 +13317,7 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -13325,7 +13317,7 @@ fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 13325 | | 13317 | |
| 13326 | if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { | 13318 | if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { |
| 13327 | const target = sema.mod.getTarget(); | 13319 | const target = sema.mod.getTarget(); |
| 13328 | const result_val = try val.intToFloat(sema.arena, dest_ty, target); | 13320 | const result_val = try val.intToFloat(sema.arena, operand_ty, dest_ty, target); |
| 13329 | return sema.addConstant(dest_ty, result_val); | 13321 | return sema.addConstant(dest_ty, result_val); |
| 13330 | } | 13322 | } |
| 13331 | | 13323 | |
| ... | @@ -13535,14 +13527,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13535,14 +13527,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13535 | if (!is_vector) { | 13527 | if (!is_vector) { |
| 13536 | return sema.addConstant( | 13528 | return sema.addConstant( |
| 13537 | dest_ty, | 13529 | dest_ty, |
| 13538 | try val.intTrunc(sema.arena, dest_info.signedness, dest_info.bits), | 13530 | try val.intTrunc(operand_ty, sema.arena, dest_info.signedness, dest_info.bits), |
| 13539 | ); | 13531 | ); |
| 13540 | } | 13532 | } |
| 13541 | var elem_buf: Value.ElemValueBuffer = undefined; | 13533 | var elem_buf: Value.ElemValueBuffer = undefined; |
| 13542 | const elems = try sema.arena.alloc(Value, operand_ty.vectorLen()); | 13534 | const elems = try sema.arena.alloc(Value, operand_ty.vectorLen()); |
| 13543 | for (elems) |*elem, i| { | 13535 | for (elems) |*elem, i| { |
| 13544 | const elem_val = val.elemValueBuffer(i, &elem_buf); | 13536 | const elem_val = val.elemValueBuffer(i, &elem_buf); |
| 13545 | elem.* = try elem_val.intTrunc(sema.arena, dest_info.signedness, dest_info.bits); | 13537 | elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits); |
| 13546 | } | 13538 | } |
| 13547 | return sema.addConstant( | 13539 | return sema.addConstant( |
| 13548 | dest_ty, | 13540 | dest_ty, |
| ... | @@ -14097,13 +14089,40 @@ fn checkSimdBinOp( | ... | @@ -14097,13 +14089,40 @@ fn checkSimdBinOp( |
| 14097 | ) CompileError!SimdBinOp { | 14089 | ) CompileError!SimdBinOp { |
| 14098 | const lhs_ty = sema.typeOf(uncasted_lhs); | 14090 | const lhs_ty = sema.typeOf(uncasted_lhs); |
| 14099 | const rhs_ty = sema.typeOf(uncasted_rhs); | 14091 | const rhs_ty = sema.typeOf(uncasted_rhs); |
| 14100 | const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison(); | | |
| 14101 | const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(); | | |
| 14102 | | 14092 | |
| 14103 | var vec_len: ?usize = null; | 14093 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| | 14094 | var vec_len: ?usize = if (lhs_ty.zigTypeTag() == .Vector) lhs_ty.vectorLen() else null; |
| | 14095 | const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{ |
| | 14096 | .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, |
| | 14097 | }); |
| | 14098 | const lhs = try sema.coerce(block, result_ty, uncasted_lhs, lhs_src); |
| | 14099 | const rhs = try sema.coerce(block, result_ty, uncasted_rhs, rhs_src); |
| | 14100 | |
| | 14101 | return SimdBinOp{ |
| | 14102 | .len = vec_len, |
| | 14103 | .lhs = lhs, |
| | 14104 | .rhs = rhs, |
| | 14105 | .lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs), |
| | 14106 | .rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs), |
| | 14107 | .result_ty = result_ty, |
| | 14108 | .scalar_ty = result_ty.scalarType(), |
| | 14109 | }; |
| | 14110 | } |
| | 14111 | |
| | 14112 | fn checkVectorizableBinaryOperands( |
| | 14113 | sema: *Sema, |
| | 14114 | block: *Block, |
| | 14115 | src: LazySrcLoc, |
| | 14116 | lhs_ty: Type, |
| | 14117 | rhs_ty: Type, |
| | 14118 | lhs_src: LazySrcLoc, |
| | 14119 | rhs_src: LazySrcLoc, |
| | 14120 | ) CompileError!void { |
| | 14121 | const lhs_zig_ty_tag = lhs_ty.zigTypeTag(); |
| | 14122 | const rhs_zig_ty_tag = rhs_ty.zigTypeTag(); |
| 14104 | if (lhs_zig_ty_tag == .Vector and rhs_zig_ty_tag == .Vector) { | 14123 | if (lhs_zig_ty_tag == .Vector and rhs_zig_ty_tag == .Vector) { |
| 14105 | const lhs_len = lhs_ty.arrayLen(); | 14124 | const lhs_len = lhs_ty.vectorLen(); |
| 14106 | const rhs_len = rhs_ty.arrayLen(); | 14125 | const rhs_len = rhs_ty.vectorLen(); |
| 14107 | if (lhs_len != rhs_len) { | 14126 | if (lhs_len != rhs_len) { |
| 14108 | const msg = msg: { | 14127 | const msg = msg: { |
| 14109 | const msg = try sema.errMsg(block, src, "vector length mismatch", .{}); | 14128 | const msg = try sema.errMsg(block, src, "vector length mismatch", .{}); |
| ... | @@ -14114,7 +14133,6 @@ fn checkSimdBinOp( | ... | @@ -14114,7 +14133,6 @@ fn checkSimdBinOp( |
| 14114 | }; | 14133 | }; |
| 14115 | return sema.failWithOwnedErrorMsg(block, msg); | 14134 | return sema.failWithOwnedErrorMsg(block, msg); |
| 14116 | } | 14135 | } |
| 14117 | vec_len = try sema.usizeCast(block, lhs_src, lhs_len); | | |
| 14118 | } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) { | 14136 | } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) { |
| 14119 | const msg = msg: { | 14137 | const msg = msg: { |
| 14120 | const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: {} and {}", .{ | 14138 | const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: {} and {}", .{ |
| ... | @@ -14132,21 +14150,6 @@ fn checkSimdBinOp( | ... | @@ -14132,21 +14150,6 @@ fn checkSimdBinOp( |
| 14132 | }; | 14150 | }; |
| 14133 | return sema.failWithOwnedErrorMsg(block, msg); | 14151 | return sema.failWithOwnedErrorMsg(block, msg); |
| 14134 | } | 14152 | } |
| 14135 | const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{ | | |
| 14136 | .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, | | |
| 14137 | }); | | |
| 14138 | const lhs = try sema.coerce(block, result_ty, uncasted_lhs, lhs_src); | | |
| 14139 | const rhs = try sema.coerce(block, result_ty, uncasted_rhs, rhs_src); | | |
| 14140 | | | |
| 14141 | return SimdBinOp{ | | |
| 14142 | .len = vec_len, | | |
| 14143 | .lhs = lhs, | | |
| 14144 | .rhs = rhs, | | |
| 14145 | .lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, lhs), | | |
| 14146 | .rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, rhs), | | |
| 14147 | .result_ty = result_ty, | | |
| 14148 | .scalar_ty = result_ty.scalarType(), | | |
| 14149 | }; | | |
| 14150 | } | 14153 | } |
| 14151 | | 14154 | |
| 14152 | fn resolveExportOptions( | 14155 | fn resolveExportOptions( |
| ... | @@ -14376,9 +14379,9 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -14376,9 +14379,9 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14376 | while (i < vec_len) : (i += 1) { | 14379 | while (i < vec_len) : (i += 1) { |
| 14377 | const elem_val = operand_val.elemValueBuffer(i, &elem_buf); | 14380 | const elem_val = operand_val.elemValueBuffer(i, &elem_buf); |
| 14378 | switch (operation) { | 14381 | switch (operation) { |
| 14379 | .And => accum = try accum.bitwiseAnd(elem_val, sema.arena), | 14382 | .And => accum = try accum.bitwiseAnd(elem_val, scalar_ty, sema.arena), |
| 14380 | .Or => accum = try accum.bitwiseOr(elem_val, sema.arena), | 14383 | .Or => accum = try accum.bitwiseOr(elem_val, scalar_ty, sema.arena), |
| 14381 | .Xor => accum = try accum.bitwiseXor(elem_val, sema.arena), | 14384 | .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena), |
| 14382 | .Min => accum = accum.numberMin(elem_val), | 14385 | .Min => accum = accum.numberMin(elem_val), |
| 14383 | .Max => accum = accum.numberMax(elem_val), | 14386 | .Max => accum = accum.numberMax(elem_val), |
| 14384 | .Add => accum = try accum.numberAddWrap(elem_val, scalar_ty, sema.arena, target), | 14387 | .Add => accum = try accum.numberAddWrap(elem_val, scalar_ty, sema.arena, target), |
| ... | @@ -14697,10 +14700,10 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -14697,10 +14700,10 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 14697 | .Xchg => operand_val, | 14700 | .Xchg => operand_val, |
| 14698 | .Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target), | 14701 | .Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target), |
| 14699 | .Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target), | 14702 | .Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target), |
| 14700 | .And => try stored_val.bitwiseAnd (operand_val, sema.arena), | 14703 | .And => try stored_val.bitwiseAnd (operand_val, operand_ty, sema.arena), |
| 14701 | .Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena, target), | 14704 | .Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena, target), |
| 14702 | .Or => try stored_val.bitwiseOr (operand_val, sema.arena), | 14705 | .Or => try stored_val.bitwiseOr (operand_val, operand_ty, sema.arena), |
| 14703 | .Xor => try stored_val.bitwiseXor (operand_val, sema.arena), | 14706 | .Xor => try stored_val.bitwiseXor (operand_val, operand_ty, sema.arena), |
| 14704 | .Max => stored_val.numberMax (operand_val), | 14707 | .Max => stored_val.numberMax (operand_val), |
| 14705 | .Min => stored_val.numberMin (operand_val), | 14708 | .Min => stored_val.numberMin (operand_val), |
| 14706 | // zig fmt: on | 14709 | // zig fmt: on |
| ... | @@ -17523,7 +17526,7 @@ fn coerce( | ... | @@ -17523,7 +17526,7 @@ fn coerce( |
| 17523 | if (val.floatHasFraction()) { | 17526 | if (val.floatHasFraction()) { |
| 17524 | return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val.fmtValue(inst_ty), dest_ty }); | 17527 | return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val.fmtValue(inst_ty), dest_ty }); |
| 17525 | } | 17528 | } |
| 17526 | const result_val = val.floatToInt(sema.arena, dest_ty, target) catch |err| switch (err) { | 17529 | const result_val = val.floatToInt(sema.arena, inst_ty, dest_ty, target) catch |err| switch (err) { |
| 17527 | error.FloatCannotFit => { | 17530 | error.FloatCannotFit => { |
| 17528 | return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty }); | 17531 | return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty }); |
| 17529 | }, | 17532 | }, |
| ... | @@ -17586,7 +17589,7 @@ fn coerce( | ... | @@ -17586,7 +17589,7 @@ fn coerce( |
| 17586 | }, | 17589 | }, |
| 17587 | .Int, .ComptimeInt => int: { | 17590 | .Int, .ComptimeInt => int: { |
| 17588 | const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :int; | 17591 | const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse break :int; |
| 17589 | const result_val = try val.intToFloat(sema.arena, dest_ty, target); | 17592 | const result_val = try val.intToFloat(sema.arena, inst_ty, dest_ty, target); |
| 17590 | // TODO implement this compile error | 17593 | // TODO implement this compile error |
| 17591 | //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty); | 17594 | //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty); |
| 17592 | //if (!int_again_val.eql(val, inst_ty)) { | 17595 | //if (!int_again_val.eql(val, inst_ty)) { |
| ... | @@ -17823,8 +17826,21 @@ fn coerceInMemoryAllowed( | ... | @@ -17823,8 +17826,21 @@ fn coerceInMemoryAllowed( |
| 17823 | return .ok; | 17826 | return .ok; |
| 17824 | } | 17827 | } |
| 17825 | | 17828 | |
| | 17829 | // Vectors |
| | 17830 | if (dest_tag == .Vector and src_tag == .Vector) vectors: { |
| | 17831 | const dest_len = dest_ty.vectorLen(); |
| | 17832 | const src_len = src_ty.vectorLen(); |
| | 17833 | if (dest_len != src_len) break :vectors; |
| | 17834 | |
| | 17835 | const dest_elem_ty = dest_ty.scalarType(); |
| | 17836 | const src_elem_ty = src_ty.scalarType(); |
| | 17837 | const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src); |
| | 17838 | if (child == .no_match) break :vectors; |
| | 17839 | |
| | 17840 | return .ok; |
| | 17841 | } |
| | 17842 | |
| 17826 | // TODO: non-pointer-like optionals | 17843 | // TODO: non-pointer-like optionals |
| 17827 | // TODO: vectors | | |
| 17828 | | 17844 | |
| 17829 | return .no_match; | 17845 | return .no_match; |
| 17830 | } | 17846 | } |
| ... | @@ -19697,19 +19713,6 @@ fn cmpNumeric( | ... | @@ -19697,19 +19713,6 @@ fn cmpNumeric( |
| 19697 | const lhs_ty_tag = lhs_ty.zigTypeTag(); | 19713 | const lhs_ty_tag = lhs_ty.zigTypeTag(); |
| 19698 | const rhs_ty_tag = rhs_ty.zigTypeTag(); | 19714 | const rhs_ty_tag = rhs_ty.zigTypeTag(); |
| 19699 | | 19715 | |
| 19700 | if (lhs_ty_tag == .Vector and rhs_ty_tag == .Vector) { | | |
| 19701 | if (lhs_ty.vectorLen() != rhs_ty.vectorLen()) { | | |
| 19702 | return sema.fail(block, src, "vector length mismatch: {d} and {d}", .{ | | |
| 19703 | lhs_ty.vectorLen(), rhs_ty.vectorLen(), | | |
| 19704 | }); | | |
| 19705 | } | | |
| 19706 | return sema.fail(block, src, "TODO implement support for vectors in cmpNumeric", .{}); | | |
| 19707 | } else if (lhs_ty_tag == .Vector or rhs_ty_tag == .Vector) { | | |
| 19708 | return sema.fail(block, src, "mixed scalar and vector operands to comparison operator: '{}' and '{}'", .{ | | |
| 19709 | lhs_ty, rhs_ty, | | |
| 19710 | }); | | |
| 19711 | } | | |
| 19712 | | | |
| 19713 | const runtime_src: LazySrcLoc = src: { | 19716 | const runtime_src: LazySrcLoc = src: { |
| 19714 | if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| { | 19717 | if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| { |
| 19715 | if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| { | 19718 | if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| { |
| ... | @@ -19895,6 +19898,46 @@ fn cmpNumeric( | ... | @@ -19895,6 +19898,46 @@ fn cmpNumeric( |
| 19895 | return block.addBinOp(Air.Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs); | 19898 | return block.addBinOp(Air.Inst.Tag.fromCmpOp(op), casted_lhs, casted_rhs); |
| 19896 | } | 19899 | } |
| 19897 | | 19900 | |
| | 19901 | /// Asserts that lhs and rhs types are both vectors. |
| | 19902 | fn cmpVector( |
| | 19903 | sema: *Sema, |
| | 19904 | block: *Block, |
| | 19905 | src: LazySrcLoc, |
| | 19906 | lhs: Air.Inst.Ref, |
| | 19907 | rhs: Air.Inst.Ref, |
| | 19908 | op: std.math.CompareOperator, |
| | 19909 | lhs_src: LazySrcLoc, |
| | 19910 | rhs_src: LazySrcLoc, |
| | 19911 | ) CompileError!Air.Inst.Ref { |
| | 19912 | const lhs_ty = sema.typeOf(lhs); |
| | 19913 | const rhs_ty = sema.typeOf(rhs); |
| | 19914 | assert(lhs_ty.zigTypeTag() == .Vector); |
| | 19915 | assert(rhs_ty.zigTypeTag() == .Vector); |
| | 19916 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| | 19917 | |
| | 19918 | const result_ty = try Type.vector(sema.arena, lhs_ty.vectorLen(), Type.@"bool"); |
| | 19919 | |
| | 19920 | const runtime_src: LazySrcLoc = src: { |
| | 19921 | if (try sema.resolveMaybeUndefVal(block, lhs_src, lhs)) |lhs_val| { |
| | 19922 | if (try sema.resolveMaybeUndefVal(block, rhs_src, rhs)) |rhs_val| { |
| | 19923 | if (lhs_val.isUndef() or rhs_val.isUndef()) { |
| | 19924 | return sema.addConstUndef(result_ty); |
| | 19925 | } |
| | 19926 | const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena); |
| | 19927 | return sema.addConstant(result_ty, cmp_val); |
| | 19928 | } else { |
| | 19929 | break :src rhs_src; |
| | 19930 | } |
| | 19931 | } else { |
| | 19932 | break :src lhs_src; |
| | 19933 | } |
| | 19934 | }; |
| | 19935 | |
| | 19936 | try sema.requireRuntimeBlock(block, runtime_src); |
| | 19937 | const result_ty_inst = try sema.addType(result_ty); |
| | 19938 | return block.addCmpVector(lhs, rhs, op, result_ty_inst); |
| | 19939 | } |
| | 19940 | |
| 19898 | fn wrapOptional( | 19941 | fn wrapOptional( |
| 19899 | sema: *Sema, | 19942 | sema: *Sema, |
| 19900 | block: *Block, | 19943 | block: *Block, |
| ... | @@ -21201,7 +21244,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -21201,7 +21244,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 21201 | map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty }); | 21244 | map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty }); |
| 21202 | } else { | 21245 | } else { |
| 21203 | const val = if (last_tag_val) |val| | 21246 | const val = if (last_tag_val) |val| |
| 21204 | try val.intAdd(Value.one, sema.arena) | 21247 | try val.intAdd(Value.one, int_tag_ty, sema.arena) |
| 21205 | else | 21248 | else |
| 21206 | Value.zero; | 21249 | Value.zero; |
| 21207 | last_tag_val = val; | 21250 | last_tag_val = val; |