| ... | @@ -1171,11 +1171,11 @@ fn analyzeBodyInner( | ... | @@ -1171,11 +1171,11 @@ fn analyzeBodyInner( |
| 1171 | .as_node => try sema.zirAsNode(block, inst), | 1171 | .as_node => try sema.zirAsNode(block, inst), |
| 1172 | .as_shift_operand => try sema.zirAsShiftOperand(block, inst), | 1172 | .as_shift_operand => try sema.zirAsShiftOperand(block, inst), |
| 1173 | .bit_and => try sema.zirBitwise(block, inst, .bit_and), | 1173 | .bit_and => try sema.zirBitwise(block, inst, .bit_and), |
| 1174 | .bit_not => try sema.zirBitNot(block, inst, false), | 1174 | .bit_not => try sema.zirBitNot(block, inst), |
| 1175 | .bit_or => try sema.zirBitwise(block, inst, .bit_or), | 1175 | .bit_or => try sema.zirBitwise(block, inst, .bit_or), |
| 1176 | .bitcast => try sema.zirBitcast(block, inst), | 1176 | .bitcast => try sema.zirBitcast(block, inst), |
| 1177 | .suspend_block => try sema.zirSuspendBlock(block, inst), | 1177 | .suspend_block => try sema.zirSuspendBlock(block, inst), |
| 1178 | .bool_not => try sema.zirBitNot(block, inst, true), | 1178 | .bool_not => try sema.zirBoolNot(block, inst), |
| 1179 | .bool_br_and => try sema.zirBoolBr(block, inst, false), | 1179 | .bool_br_and => try sema.zirBoolBr(block, inst, false), |
| 1180 | .bool_br_or => try sema.zirBoolBr(block, inst, true), | 1180 | .bool_br_or => try sema.zirBoolBr(block, inst, true), |
| 1181 | .c_import => try sema.zirCImport(block, inst), | 1181 | .c_import => try sema.zirCImport(block, inst), |
| ... | @@ -14464,57 +14464,55 @@ fn zirBitwise( | ... | @@ -14464,57 +14464,55 @@ fn zirBitwise( |
| 14464 | return block.addBinOp(air_tag, casted_lhs, casted_rhs); | 14464 | return block.addBinOp(air_tag, casted_lhs, casted_rhs); |
| 14465 | } | 14465 | } |
| 14466 | | 14466 | |
| 14467 | fn zirBitNot( | 14467 | fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 14468 | sema: *Sema, | | |
| 14469 | block: *Block, | | |
| 14470 | inst: Zir.Inst.Index, | | |
| 14471 | is_bool_not: bool, | | |
| 14472 | ) CompileError!Air.Inst.Ref { | | |
| 14473 | const tracy = trace(@src()); | | |
| 14474 | defer tracy.end(); | | |
| 14475 | | | |
| 14476 | const pt = sema.pt; | 14468 | const pt = sema.pt; |
| 14477 | const zcu = pt.zcu; | 14469 | const zcu = pt.zcu; |
| 14478 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; | 14470 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 14479 | const src = block.nodeOffset(inst_data.src_node); | | |
| 14480 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); | 14471 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); |
| 14481 | | 14472 | const src = block.nodeOffset(inst_data.src_node); |
| 14482 | const operand = try sema.resolveInst(inst_data.operand); | 14473 | const operand = try sema.resolveInst(inst_data.operand); |
| 14483 | const operand_type = sema.typeOf(operand); | 14474 | const operand_ty = sema.typeOf(operand); |
| 14484 | const scalar_type = operand_type.scalarType(zcu); | 14475 | const scalar_ty = operand_ty.scalarType(zcu); |
| 14485 | const scalar_tag = scalar_type.zigTypeTag(zcu); | 14476 | const scalar_tag = scalar_ty.zigTypeTag(zcu); |
| 14486 | | 14477 | |
| 14487 | const is_finite_int_or_bool = scalar_tag == .int or scalar_tag == .bool; | 14478 | if (scalar_tag != .int and scalar_tag != .bool) |
| 14488 | const is_allowed_type = if (is_bool_not) scalar_tag == .bool else is_finite_int_or_bool; | 14479 | return sema.fail(block, operand_src, "bitwise not operation on type '{}'", .{operand_ty.fmt(pt)}); |
| 14489 | | 14480 | |
| 14490 | if (!is_allowed_type) { | 14481 | return analyzeBitNot(sema, block, operand, src); |
| 14491 | return sema.fail(block, src, "unable to perform {s} not operation on type '{}'", .{ | 14482 | } |
| 14492 | if (is_bool_not) "boolean" else "binary", operand_type.fmt(pt), | | |
| 14493 | }); | | |
| 14494 | } | | |
| 14495 | | 14483 | |
| | 14484 | fn analyzeBitNot( |
| | 14485 | sema: *Sema, |
| | 14486 | block: *Block, |
| | 14487 | operand: Air.Inst.Ref, |
| | 14488 | src: LazySrcLoc, |
| | 14489 | ) CompileError!Air.Inst.Ref { |
| | 14490 | const pt = sema.pt; |
| | 14491 | const zcu = pt.zcu; |
| | 14492 | const operand_ty = sema.typeOf(operand); |
| | 14493 | const scalar_ty = operand_ty.scalarType(zcu); |
| 14496 | if (try sema.resolveValue(operand)) |val| { | 14494 | if (try sema.resolveValue(operand)) |val| { |
| 14497 | if (val.isUndef(zcu)) { | 14495 | if (val.isUndef(zcu)) { |
| 14498 | return pt.undefRef(operand_type); | 14496 | return pt.undefRef(operand_ty); |
| 14499 | } else if (operand_type.zigTypeTag(zcu) == .vector) { | 14497 | } else if (operand_ty.zigTypeTag(zcu) == .vector) { |
| 14500 | const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(zcu)); | 14498 | const vec_len = try sema.usizeCast(block, src, operand_ty.vectorLen(zcu)); |
| 14501 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); | 14499 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 14502 | for (elems, 0..) |*elem, i| { | 14500 | for (elems, 0..) |*elem, i| { |
| 14503 | const elem_val = try val.elemValue(pt, i); | 14501 | const elem_val = try val.elemValue(pt, i); |
| 14504 | elem.* = (try elem_val.bitwiseNot(scalar_type, sema.arena, pt)).toIntern(); | 14502 | elem.* = (try elem_val.bitwiseNot(scalar_ty, sema.arena, pt)).toIntern(); |
| 14505 | } | 14503 | } |
| 14506 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ | 14504 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 14507 | .ty = operand_type.toIntern(), | 14505 | .ty = operand_ty.toIntern(), |
| 14508 | .storage = .{ .elems = elems }, | 14506 | .storage = .{ .elems = elems }, |
| 14509 | } }))); | 14507 | } }))); |
| 14510 | } else { | 14508 | } else { |
| 14511 | const result_val = try val.bitwiseNot(operand_type, sema.arena, pt); | 14509 | const result_val = try val.bitwiseNot(operand_ty, sema.arena, pt); |
| 14512 | return Air.internedToRef(result_val.toIntern()); | 14510 | return Air.internedToRef(result_val.toIntern()); |
| 14513 | } | 14511 | } |
| 14514 | } | 14512 | } |
| 14515 | | 14513 | |
| 14516 | try sema.requireRuntimeBlock(block, src, null); | 14514 | try sema.requireRuntimeBlock(block, src, null); |
| 14517 | return block.addTyOp(.not, operand_type, operand); | 14515 | return block.addTyOp(.not, operand_ty, operand); |
| 14518 | } | 14516 | } |
| 14519 | | 14517 | |
| 14520 | fn analyzeTupleCat( | 14518 | fn analyzeTupleCat( |
| ... | @@ -18367,6 +18365,30 @@ fn zirTypeofPeer( | ... | @@ -18367,6 +18365,30 @@ fn zirTypeofPeer( |
| 18367 | return Air.internedToRef(result_type.toIntern()); | 18365 | return Air.internedToRef(result_type.toIntern()); |
| 18368 | } | 18366 | } |
| 18369 | | 18367 | |
| | 18368 | fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| | 18369 | const pt = sema.pt; |
| | 18370 | const zcu = pt.zcu; |
| | 18371 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| | 18372 | const src = block.nodeOffset(inst_data.src_node); |
| | 18373 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); |
| | 18374 | const uncasted_operand = try sema.resolveInst(inst_data.operand); |
| | 18375 | const uncasted_ty = sema.typeOf(uncasted_operand); |
| | 18376 | if (uncasted_ty.isVector(zcu)) { |
| | 18377 | if (uncasted_ty.scalarType(zcu).zigTypeTag(zcu) != .bool) { |
| | 18378 | return sema.fail(block, operand_src, "boolean not operation on type '{}'", .{ |
| | 18379 | uncasted_ty.fmt(pt), |
| | 18380 | }); |
| | 18381 | } |
| | 18382 | return analyzeBitNot(sema, block, uncasted_operand, src); |
| | 18383 | } |
| | 18384 | const operand = try sema.coerce(block, .bool, uncasted_operand, operand_src); |
| | 18385 | if (try sema.resolveValue(operand)) |val| { |
| | 18386 | return if (val.isUndef(zcu)) .undef_bool else if (val.toBool()) .bool_false else .bool_true; |
| | 18387 | } |
| | 18388 | try sema.requireRuntimeBlock(block, src, null); |
| | 18389 | return block.addTyOp(.not, .bool, operand); |
| | 18390 | } |
| | 18391 | |
| 18370 | fn zirBoolBr( | 18392 | fn zirBoolBr( |
| 18371 | sema: *Sema, | 18393 | sema: *Sema, |
| 18372 | parent_block: *Block, | 18394 | parent_block: *Block, |