aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorLemonBoy <thatlemon@gmail.com>2019-09-09 19:09:56 +0200
committerLemonBoy <thatlemon@gmail.com>2019-09-09 19:09:56 +0200
commit4b1cd45472cab5569438fef018990fbe8043c6c3 (patch)
treeae1f233ad992910d92b3882202cda30808491d4e /src/ir.cpp
parentcc6376058784aa7a910e93c31ac8bd819de4e187 (diff)
downloadzig-4b1cd45472cab5569438fef018990fbe8043c6c3.tar.gz
zig-4b1cd45472cab5569438fef018990fbe8043c6c3.zip
Comptime folding of enum/union comparisons
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index bbea993162..196e84eead 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -13247,6 +13247,21 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
if (type_is_invalid(casted_val->value.type))
return ira->codegen->invalid_instruction;
+ if (instr_is_comptime(casted_union)) {
+ ConstExprValue *const_union_val = ir_resolve_const(ira, casted_union, UndefBad);
+ if (!const_union_val)
+ return ira->codegen->invalid_instruction;
+
+ ConstExprValue *const_enum_val = ir_resolve_const(ira, casted_val, UndefBad);
+ if (!const_enum_val)
+ return ira->codegen->invalid_instruction;
+
+ Cmp cmp_result = bigint_cmp(&const_union_val->data.x_union.tag, &const_enum_val->data.x_enum_tag);
+ bool bool_result = (op_id == IrBinOpCmpEq) ? cmp_result == CmpEQ : cmp_result != CmpEQ;
+
+ return ir_const_bool(ira, &bin_op_instruction->base, bool_result);
+ }
+
IrInstruction *result = ir_build_bin_op(&ira->new_irb,
bin_op_instruction->base.scope, bin_op_instruction->base.source_node,
op_id, casted_union, casted_val, bin_op_instruction->safety_check_on);