| ... | ... | @@ -1171,11 +1171,11 @@ fn analyzeBodyInner( |
| 1171 | 1171 | .as_node => try sema.zirAsNode(block, inst), |
| 1172 | 1172 | .as_shift_operand => try sema.zirAsShiftOperand(block, inst), |
| 1173 | 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 | 1175 | .bit_or => try sema.zirBitwise(block, inst, .bit_or), |
| 1176 | 1176 | .bitcast => try sema.zirBitcast(block, inst), |
| 1177 | 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 | 1179 | .bool_br_and => try sema.zirBoolBr(block, inst, false), |
| 1180 | 1180 | .bool_br_or => try sema.zirBoolBr(block, inst, true), |
| 1181 | 1181 | .c_import => try sema.zirCImport(block, inst), |
| ... | ... | @@ -14464,57 +14464,55 @@ fn zirBitwise( |
| 14464 | 14464 | return block.addBinOp(air_tag, casted_lhs, casted_rhs); |
| 14465 | 14465 | } |
| 14466 | 14466 | |
| 14467 | | fn zirBitNot( |
| 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 | | |
| 14467 | fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 14476 | 14468 | const pt = sema.pt; |
| 14477 | 14469 | const zcu = pt.zcu; |
| 14478 | 14470 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; |
| 14479 | | const src = block.nodeOffset(inst_data.src_node); |
| 14480 | 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 | 14473 | const operand = try sema.resolveInst(inst_data.operand); |
| 14483 | | const operand_type = sema.typeOf(operand); |
| 14484 | | const scalar_type = operand_type.scalarType(zcu); |
| 14485 | | const scalar_tag = scalar_type.zigTypeTag(zcu); |
| 14474 | const operand_ty = sema.typeOf(operand); |
| 14475 | const scalar_ty = operand_ty.scalarType(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; |
| 14488 | | const is_allowed_type = if (is_bool_not) scalar_tag == .bool else is_finite_int_or_bool; |
| 14478 | if (scalar_tag != .int and scalar_tag != .bool) |
| 14479 | return sema.fail(block, operand_src, "bitwise not operation on type '{}'", .{operand_ty.fmt(pt)}); |
| 14489 | 14480 | |
| 14490 | | if (!is_allowed_type) { |
| 14491 | | return sema.fail(block, src, "unable to perform {s} not operation on type '{}'", .{ |
| 14492 | | if (is_bool_not) "boolean" else "binary", operand_type.fmt(pt), |
| 14493 | | }); |
| 14494 | | } |
| 14481 | return analyzeBitNot(sema, block, operand, src); |
| 14482 | } |
| 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 | 14494 | if (try sema.resolveValue(operand)) |val| { |
| 14497 | 14495 | if (val.isUndef(zcu)) { |
| 14498 | | return pt.undefRef(operand_type); |
| 14499 | | } else if (operand_type.zigTypeTag(zcu) == .vector) { |
| 14500 | | const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(zcu)); |
| 14496 | return pt.undefRef(operand_ty); |
| 14497 | } else if (operand_ty.zigTypeTag(zcu) == .vector) { |
| 14498 | const vec_len = try sema.usizeCast(block, src, operand_ty.vectorLen(zcu)); |
| 14501 | 14499 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 14502 | 14500 | for (elems, 0..) |*elem, i| { |
| 14503 | 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 | 14504 | return Air.internedToRef((try pt.intern(.{ .aggregate = .{ |
| 14507 | | .ty = operand_type.toIntern(), |
| 14505 | .ty = operand_ty.toIntern(), |
| 14508 | 14506 | .storage = .{ .elems = elems }, |
| 14509 | 14507 | } }))); |
| 14510 | 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 | 14510 | return Air.internedToRef(result_val.toIntern()); |
| 14513 | 14511 | } |
| 14514 | 14512 | } |
| 14515 | 14513 | |
| 14516 | 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 | 14518 | fn analyzeTupleCat( |
| ... | ... | @@ -18367,6 +18365,30 @@ fn zirTypeofPeer( |
| 18367 | 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 | 18392 | fn zirBoolBr( |
| 18371 | 18393 | sema: *Sema, |
| 18372 | 18394 | parent_block: *Block, |