diff options
| -rw-r--r-- | Documentation/dev-options.rst | 1 | ||||
| -rw-r--r-- | lib.c | 1 | ||||
| -rw-r--r-- | linearize.c | 141 | ||||
| -rw-r--r-- | sparse.c | 2 | ||||
| -rw-r--r-- | validation/linear/asm-toplevel.c (renamed from validation/asm-toplevel.c) | 0 | ||||
| -rw-r--r-- | validation/linear/logical-phi0.c | 48 | ||||
| -rw-r--r-- | validation/linear/logical.c | 180 | ||||
| -rw-r--r-- | validation/linear/missing-return0.c | 10 | ||||
| -rw-r--r-- | validation/linear/missing-return1.c | 15 | ||||
| -rw-r--r-- | validation/linear/missing-return2.c | 11 | ||||
| -rw-r--r-- | validation/linear/missing-return3.c | 18 | ||||
| -rw-r--r-- | validation/linear/missing-return4.c | 14 | ||||
| -rw-r--r-- | validation/linear/missing-return5.c | 23 | ||||
| -rw-r--r-- | validation/linear/phi-order01.c | 16 | ||||
| -rw-r--r-- | validation/linear/phi-order02.c | 16 | ||||
| -rw-r--r-- | validation/linear/phi-order03.c | 8 | ||||
| -rw-r--r-- | validation/linear/phi-order04.c | 12 |
17 files changed, 373 insertions, 143 deletions
diff --git a/Documentation/dev-options.rst b/Documentation/dev-options.rst index 04fb651f..23e8096c 100644 --- a/Documentation/dev-options.rst +++ b/Documentation/dev-options.rst @@ -33,6 +33,7 @@ OPTIONS The passes currently understood are: + * ``linearize`` (can't be disabled) * ``mem2reg`` * ``optim`` @@ -958,6 +958,7 @@ static int handle_fmax_warnings(const char *arg, const char *opt, const struct f static struct flag fflags[] = { { "diagnostic-prefix", NULL, handle_fdiagnostic_prefix }, { "dump-ir", NULL, handle_fdump_ir }, + { "linearize", NULL, handle_fpasses, PASS_LINEARIZE }, { "max-warnings=", NULL, handle_fmax_warnings }, { "mem-report", &fmem_report }, { "memcpy-max-count=", NULL, handle_fmemcpy_max_count }, diff --git a/linearize.c b/linearize.c index c74561c9..670e3830 100644 --- a/linearize.c +++ b/linearize.c @@ -1695,41 +1695,54 @@ static pseudo_t linearize_conditional(struct entrypoint *ep, struct expression * return add_join_conditional(ep, expr, phi1, phi2); } +static void insert_phis(struct basic_block *bb, pseudo_t src, struct symbol *ctype, + struct instruction *node) +{ + struct basic_block *parent; + + FOR_EACH_PTR(bb->parents, parent) { + struct instruction *br = delete_last_instruction(&parent->insns); + pseudo_t phi = alloc_phi(parent, src, ctype); + add_instruction(&parent->insns, br); + use_pseudo(node, phi, add_pseudo(&node->phi_list, phi)); + } END_FOR_EACH_PTR(parent); +} + static pseudo_t linearize_logical(struct entrypoint *ep, struct expression *expr) { + struct symbol *ctype = expr->ctype; struct basic_block *other, *merge; - pseudo_t phi1, phi2; + struct instruction *node; + pseudo_t src1, src2, phi2; if (!ep->active || !expr->left || !expr->right) return VOID; other = alloc_basic_block(ep, expr->right->pos); merge = alloc_basic_block(ep, expr->pos); + node = alloc_phi_node(merge, ctype, NULL); + // LHS and its shortcut if (expr->op == SPECIAL_LOGICAL_OR) { - pseudo_t src2; - - phi1 = alloc_phi(ep->active, value_pseudo(1), expr->ctype); linearize_cond_branch(ep, expr->left, merge, other); - - set_activeblock(ep, other); - src2 = linearize_expression_to_bool(ep, expr->right); - src2 = cast_pseudo(ep, src2, &bool_ctype, expr->ctype); - phi2 = alloc_phi(ep->active, src2, expr->ctype); + src1 = value_pseudo(1); } else { - pseudo_t src1; - - phi2 = alloc_phi(ep->active, value_pseudo(0), expr->ctype); linearize_cond_branch(ep, expr->left, other, merge); - - set_activeblock(ep, other); - src1 = linearize_expression_to_bool(ep, expr->right); - src1 = cast_pseudo(ep, src1, &bool_ctype, expr->ctype); - phi1 = alloc_phi(ep->active, src1, expr->ctype); + src1 = value_pseudo(0); } + insert_phis(merge, src1, ctype, node); + // RHS + set_activeblock(ep, other); + src2 = linearize_expression_to_bool(ep, expr->right); + src2 = cast_pseudo(ep, src2, &bool_ctype, ctype); + phi2 = alloc_phi(ep->active, src2, ctype); + use_pseudo(node, phi2, add_pseudo(&node->phi_list, phi2)); + + // join set_activeblock(ep, merge); - return add_join_conditional(ep, expr, phi1, phi2); + add_instruction(&merge->insns, node); + return node->target; } static pseudo_t linearize_compare(struct entrypoint *ep, struct expression *expr) @@ -1969,22 +1982,49 @@ static pseudo_t linearize_compound_statement(struct entrypoint *ep, struct state { pseudo_t pseudo; struct statement *s; - struct symbol *ret = stmt->ret; pseudo = VOID; FOR_EACH_PTR(stmt->stmts, s) { pseudo = linearize_statement(ep, s); } END_FOR_EACH_PTR(s); - if (ret) { - struct basic_block *bb = add_label(ep, ret); - struct instruction *phi_node = first_instruction(bb->insns); + return pseudo; +} - if (!phi_node) - return pseudo; - return phi_node->target; +static void add_return(struct entrypoint *ep, struct basic_block *bb, struct symbol *ctype, pseudo_t src) +{ + struct instruction *phi_node = first_instruction(bb->insns); + pseudo_t phi; + if (!phi_node) { + phi_node = alloc_typed_instruction(OP_PHI, ctype); + phi_node->target = alloc_pseudo(phi_node); + phi_node->bb = bb; + add_instruction(&bb->insns, phi_node); } + phi = alloc_phi(ep->active, src, ctype); + phi->ident = &return_ident; + use_pseudo(phi_node, phi, add_pseudo(&phi_node->phi_list, phi)); +} +static pseudo_t linearize_fn_statement(struct entrypoint *ep, struct statement *stmt) +{ + struct instruction *phi_node; + struct basic_block *bb; + pseudo_t pseudo; + + pseudo = linearize_compound_statement(ep, stmt); + if (!is_void_type(stmt->ret)) { // non-void function + struct basic_block *active = ep->active; + if (active && !bb_terminated(active)) { // missing return + struct basic_block *bb_ret; + bb_ret = get_bound_block(ep, stmt->ret); + add_return(ep, bb_ret, stmt->ret, undef_pseudo()); + } + } + bb = add_label(ep, stmt->ret); + phi_node = first_instruction(bb->insns); + if (phi_node) + pseudo = phi_node->target; return pseudo; } @@ -2005,10 +2045,12 @@ static pseudo_t linearize_inlined_call(struct entrypoint *ep, struct statement * } END_FOR_EACH_PTR(sym); } - insn->target = pseudo = linearize_compound_statement(ep, stmt); + pseudo = linearize_fn_statement(ep, stmt); + insn->target = pseudo; + use_pseudo(insn, symbol_pseudo(ep, stmt->inline_fn), &insn->func); bb = ep->active; - if (bb && !bb->insns) + if (!bb->insns) bb->pos = stmt->pos; add_one_insn(ep, insn); return pseudo; @@ -2144,22 +2186,13 @@ static pseudo_t linearize_declaration(struct entrypoint *ep, struct statement *s static pseudo_t linearize_return(struct entrypoint *ep, struct statement *stmt) { struct expression *expr = stmt->expression; - struct basic_block *bb_return = get_bound_block(ep, stmt->ret_target); + struct symbol *ret = stmt->ret_target; + struct basic_block *bb_return = get_bound_block(ep, ret); struct basic_block *active; pseudo_t src = linearize_expression(ep, expr); active = ep->active; - if (active && src != VOID) { - struct instruction *phi_node = first_instruction(bb_return->insns); - pseudo_t phi; - if (!phi_node) { - phi_node = alloc_typed_instruction(OP_PHI, expr->ctype); - phi_node->target = alloc_pseudo(phi_node); - phi_node->bb = bb_return; - add_instruction(&bb_return->insns, phi_node); - } - phi = alloc_phi(active, src, expr->ctype); - phi->ident = &return_ident; - use_pseudo(phi_node, phi, add_pseudo(&phi_node->phi_list, phi)); + if (active && !is_void_type(ret)) { + add_return(ep, bb_return, ret, src); } add_goto(ep, bb_return); return VOID; @@ -2416,23 +2449,30 @@ static pseudo_t linearize_statement(struct entrypoint *ep, struct statement *stm static struct entrypoint *linearize_fn(struct symbol *sym, struct symbol *base_type) { + struct statement *stmt = base_type->stmt; struct entrypoint *ep; struct basic_block *bb; + struct symbol *ret_type; struct symbol *arg; struct instruction *entry; + struct instruction *ret; pseudo_t result; int i; - if (!base_type->stmt) + if (!stmt) return NULL; ep = alloc_entrypoint(); - bb = alloc_basic_block(ep, sym->pos); - ep->name = sym; sym->ep = ep; + bb = alloc_basic_block(ep, sym->pos); set_activeblock(ep, bb); + if (stmt->type == STMT_ASM) { // top-level asm + linearize_asm_statement(ep, stmt); + return ep; + } + entry = alloc_instruction(OP_ENTRY, 0); add_one_insn(ep, entry); ep->entry = entry; @@ -2445,15 +2485,12 @@ static struct entrypoint *linearize_fn(struct symbol *sym, struct symbol *base_t linearize_argument(ep, arg, ++i); } END_FOR_EACH_PTR(arg); - result = linearize_statement(ep, base_type->stmt); - if (bb_reachable(ep->active) && !bb_terminated(ep->active)) { - struct symbol *ret_type = base_type->ctype.base_type; - struct instruction *insn = alloc_typed_instruction(OP_RET, ret_type); - - if (type_size(ret_type) > 0) - use_pseudo(insn, result, &insn->src); - add_one_insn(ep, insn); - } + result = linearize_fn_statement(ep, stmt); + ret_type = base_type->ctype.base_type; + ret = alloc_typed_instruction(OP_RET, ret_type); + if (type_size(ret_type) > 0) + use_pseudo(ret, result, &ret->src); + add_one_insn(ep, ret); optimize(ep); return ep; @@ -315,7 +315,7 @@ static void check_symbols(struct symbol_list *list) expand_symbol(sym); ep = linearize_symbol(sym); - if (ep) { + if (ep && ep->entry) { if (dbg_entry) show_entry(ep); diff --git a/validation/asm-toplevel.c b/validation/linear/asm-toplevel.c index 8bdd7fc1..8bdd7fc1 100644 --- a/validation/asm-toplevel.c +++ b/validation/linear/asm-toplevel.c diff --git a/validation/linear/logical-phi0.c b/validation/linear/logical-phi0.c new file mode 100644 index 00000000..96a47dba --- /dev/null +++ b/validation/linear/logical-phi0.c @@ -0,0 +1,48 @@ +int a(void); +int b(void); +int c(void); + +static int laa(void) +{ + return (a() && b()) && c(); +} + +static int lao(void) +{ + return (a() && b()) || c(); +} + +static int loa(void) +{ + return (a() || b()) && c(); +} + +static int loo(void) +{ + return (a() || b()) || c(); +} + +static int raa(void) +{ + return a() && (b() && c()); +} + +static int rao(void) +{ + return a() && (b() || c()); +} + +static int roa(void) +{ + return a() || (b() && c()); +} + +static int roo(void) +{ + return a() || (b() || c()); +} + +/* + * check-name: bad-logical-phi0 + * check-command: sparse -vir -flinearize=last $file + */ diff --git a/validation/linear/logical.c b/validation/linear/logical.c index 0f502c6b..b190f608 100644 --- a/validation/linear/logical.c +++ b/validation/linear/logical.c @@ -26,24 +26,24 @@ os: <entry-point> store.32 %arg1 -> 0[i] store.64 %arg2 -> 0[b] + load.32 %r2 <- 0[i] + setne.1 %r3 <- %r2, $0 phisrc.32 %phi1 <- $1 - load.32 %r1 <- 0[i] - setne.1 %r2 <- %r1, $0 - cbr %r2, .L3, .L2 + cbr %r3, .L3, .L2 .L2: - load.64 %r3 <- 0[b] - load.32 %r4 <- 0[%r3] - lsr.32 %r5 <- %r4, $1 - trunc.2 %r6 <- (32) %r5 - setne.1 %r7 <- %r6, $0 - zext.32 %r8 <- (1) %r7 - phisrc.32 %phi2 <- %r8 + load.64 %r4 <- 0[b] + load.32 %r5 <- 0[%r4] + lsr.32 %r6 <- %r5, $1 + trunc.2 %r7 <- (32) %r6 + setne.1 %r8 <- %r7, $0 + zext.32 %r9 <- (1) %r8 + phisrc.32 %phi2 <- %r9 br .L3 .L3: - phi.32 %r9 <- %phi1, %phi2 - phisrc.32 %phi3(return) <- %r9 + phi.32 %r1 <- %phi1, %phi2 + phisrc.32 %phi3(return) <- %r1 br .L1 .L1: @@ -56,24 +56,24 @@ ou: <entry-point> store.32 %arg1 -> 0[i] store.64 %arg2 -> 0[b] + load.32 %r12 <- 0[i] + setne.1 %r13 <- %r12, $0 phisrc.32 %phi4 <- $1 - load.32 %r11 <- 0[i] - setne.1 %r12 <- %r11, $0 - cbr %r12, .L7, .L6 + cbr %r13, .L7, .L6 .L6: - load.64 %r13 <- 0[b] - load.32 %r14 <- 0[%r13] - lsr.32 %r15 <- %r14, $3 - trunc.3 %r16 <- (32) %r15 - setne.1 %r17 <- %r16, $0 - zext.32 %r18 <- (1) %r17 - phisrc.32 %phi5 <- %r18 + load.64 %r14 <- 0[b] + load.32 %r15 <- 0[%r14] + lsr.32 %r16 <- %r15, $3 + trunc.3 %r17 <- (32) %r16 + setne.1 %r18 <- %r17, $0 + zext.32 %r19 <- (1) %r18 + phisrc.32 %phi5 <- %r19 br .L7 .L7: - phi.32 %r19 <- %phi4, %phi5 - phisrc.32 %phi6(return) <- %r19 + phi.32 %r11 <- %phi4, %phi5 + phisrc.32 %phi6(return) <- %r11 br .L5 .L5: @@ -86,22 +86,22 @@ ol: <entry-point> store.32 %arg1 -> 0[i] store.64 %arg2 -> 0[b] + load.32 %r22 <- 0[i] + setne.1 %r23 <- %r22, $0 phisrc.32 %phi7 <- $1 - load.32 %r21 <- 0[i] - setne.1 %r22 <- %r21, $0 - cbr %r22, .L11, .L10 + cbr %r23, .L11, .L10 .L10: - load.64 %r23 <- 0[b] - load.64 %r24 <- 8[%r23] - setne.1 %r25 <- %r24, $0 - zext.32 %r26 <- (1) %r25 - phisrc.32 %phi8 <- %r26 + load.64 %r24 <- 0[b] + load.64 %r25 <- 8[%r24] + setne.1 %r26 <- %r25, $0 + zext.32 %r27 <- (1) %r26 + phisrc.32 %phi8 <- %r27 br .L11 .L11: - phi.32 %r27 <- %phi7, %phi8 - phisrc.32 %phi9(return) <- %r27 + phi.32 %r21 <- %phi7, %phi8 + phisrc.32 %phi9(return) <- %r21 br .L9 .L9: @@ -114,23 +114,23 @@ od: <entry-point> store.32 %arg1 -> 0[i] store.64 %arg2 -> 0[b] + load.32 %r30 <- 0[i] + setne.1 %r31 <- %r30, $0 phisrc.32 %phi10 <- $1 - load.32 %r29 <- 0[i] - setne.1 %r30 <- %r29, $0 - cbr %r30, .L15, .L14 + cbr %r31, .L15, .L14 .L14: - load.64 %r31 <- 0[b] - load.64 %r32 <- 16[%r31] - setfval.64 %r33 <- 0.000000e+00 - fcmpune.1 %r34 <- %r32, %r33 - zext.32 %r35 <- (1) %r34 - phisrc.32 %phi11 <- %r35 + load.64 %r32 <- 0[b] + load.64 %r33 <- 16[%r32] + setfval.64 %r34 <- 0.000000e+00 + fcmpune.1 %r35 <- %r33, %r34 + zext.32 %r36 <- (1) %r35 + phisrc.32 %phi11 <- %r36 br .L15 .L15: - phi.32 %r36 <- %phi10, %phi11 - phisrc.32 %phi12(return) <- %r36 + phi.32 %r29 <- %phi10, %phi11 + phisrc.32 %phi12(return) <- %r29 br .L13 .L13: @@ -143,24 +143,24 @@ as: <entry-point> store.32 %arg1 -> 0[i] store.64 %arg2 -> 0[b] + load.32 %r39 <- 0[i] + setne.1 %r40 <- %r39, $0 phisrc.32 %phi13 <- $0 - load.32 %r38 <- 0[i] - setne.1 %r39 <- %r38, $0 - cbr %r39, .L18, .L19 + cbr %r40, .L18, .L19 .L18: - load.64 %r40 <- 0[b] - load.32 %r41 <- 0[%r40] - lsr.32 %r42 <- %r41, $1 - trunc.2 %r43 <- (32) %r42 - setne.1 %r44 <- %r43, $0 - zext.32 %r45 <- (1) %r44 - phisrc.32 %phi14 <- %r45 + load.64 %r41 <- 0[b] + load.32 %r42 <- 0[%r41] + lsr.32 %r43 <- %r42, $1 + trunc.2 %r44 <- (32) %r43 + setne.1 %r45 <- %r44, $0 + zext.32 %r46 <- (1) %r45 + phisrc.32 %phi14 <- %r46 br .L19 .L19: - phi.32 %r46 <- %phi14, %phi13 - phisrc.32 %phi15(return) <- %r46 + phi.32 %r38 <- %phi13, %phi14 + phisrc.32 %phi15(return) <- %r38 br .L17 .L17: @@ -173,24 +173,24 @@ au: <entry-point> store.32 %arg1 -> 0[i] store.64 %arg2 -> 0[b] + load.32 %r49 <- 0[i] + setne.1 %r50 <- %r49, $0 phisrc.32 %phi16 <- $0 - load.32 %r48 <- 0[i] - setne.1 %r49 <- %r48, $0 - cbr %r49, .L22, .L23 + cbr %r50, .L22, .L23 .L22: - load.64 %r50 <- 0[b] - load.32 %r51 <- 0[%r50] - lsr.32 %r52 <- %r51, $3 - trunc.3 %r53 <- (32) %r52 - setne.1 %r54 <- %r53, $0 - zext.32 %r55 <- (1) %r54 - phisrc.32 %phi17 <- %r55 + load.64 %r51 <- 0[b] + load.32 %r52 <- 0[%r51] + lsr.32 %r53 <- %r52, $3 + trunc.3 %r54 <- (32) %r53 + setne.1 %r55 <- %r54, $0 + zext.32 %r56 <- (1) %r55 + phisrc.32 %phi17 <- %r56 br .L23 .L23: - phi.32 %r56 <- %phi17, %phi16 - phisrc.32 %phi18(return) <- %r56 + phi.32 %r48 <- %phi16, %phi17 + phisrc.32 %phi18(return) <- %r48 br .L21 .L21: @@ -203,22 +203,22 @@ al: <entry-point> store.32 %arg1 -> 0[i] store.64 %arg2 -> 0[b] + load.32 %r59 <- 0[i] + setne.1 %r60 <- %r59, $0 phisrc.32 %phi19 <- $0 - load.32 %r58 <- 0[i] - setne.1 %r59 <- %r58, $0 - cbr %r59, .L26, .L27 + cbr %r60, .L26, .L27 .L26: - load.64 %r60 <- 0[b] - load.64 %r61 <- 8[%r60] - setne.1 %r62 <- %r61, $0 - zext.32 %r63 <- (1) %r62 - phisrc.32 %phi20 <- %r63 + load.64 %r61 <- 0[b] + load.64 %r62 <- 8[%r61] + setne.1 %r63 <- %r62, $0 + zext.32 %r64 <- (1) %r63 + phisrc.32 %phi20 <- %r64 br .L27 .L27: - phi.32 %r64 <- %phi20, %phi19 - phisrc.32 %phi21(return) <- %r64 + phi.32 %r58 <- %phi19, %phi20 + phisrc.32 %phi21(return) <- %r58 br .L25 .L25: @@ -231,23 +231,23 @@ ad: <entry-point> store.32 %arg1 -> 0[i] store.64 %arg2 -> 0[b] + load.32 %r67 <- 0[i] + setne.1 %r68 <- %r67, $0 phisrc.32 %phi22 <- $0 - load.32 %r66 <- 0[i] - setne.1 %r67 <- %r66, $0 - cbr %r67, .L30, .L31 + cbr %r68, .L30, .L31 .L30: - load.64 %r68 <- 0[b] - load.64 %r69 <- 16[%r68] - setfval.64 %r70 <- 0.000000e+00 - fcmpune.1 %r71 <- %r69, %r70 - zext.32 %r72 <- (1) %r71 - phisrc.32 %phi23 <- %r72 + load.64 %r69 <- 0[b] + load.64 %r70 <- 16[%r69] + setfval.64 %r71 <- 0.000000e+00 + fcmpune.1 %r72 <- %r70, %r71 + zext.32 %r73 <- (1) %r72 + phisrc.32 %phi23 <- %r73 br .L31 .L31: - phi.32 %r73 <- %phi23, %phi22 - phisrc.32 %phi24(return) <- %r73 + phi.32 %r66 <- %phi22, %phi23 + phisrc.32 %phi24(return) <- %r66 br .L29 .L29: diff --git a/validation/linear/missing-return0.c b/validation/linear/missing-return0.c new file mode 100644 index 00000000..77ab5abd --- /dev/null +++ b/validation/linear/missing-return0.c @@ -0,0 +1,10 @@ +static int foo(int a) +{ + if (a) + return 1; +} + +/* + * check-name: missing-return0 + * check-command: sparse -vir -flinearize=last $file + */ diff --git a/validation/linear/missing-return1.c b/validation/linear/missing-return1.c new file mode 100644 index 00000000..4a8a9517 --- /dev/null +++ b/validation/linear/missing-return1.c @@ -0,0 +1,15 @@ +static inline int fun(int a) +{ + if (a) + return 1; +} + +static int foo(int a) +{ + return fun(a); +} + +/* + * check-name: missing-return1 + * check-command: sparse -vir -flinearize=last $file + */ diff --git a/validation/linear/missing-return2.c b/validation/linear/missing-return2.c new file mode 100644 index 00000000..395dcc14 --- /dev/null +++ b/validation/linear/missing-return2.c @@ -0,0 +1,11 @@ +static int foo(int a) +{ + switch (a) + case 3: + return 4; +} + +/* + * check-name: missing-return2 + * check-command: sparse -vir -flinearize=last $file + */ diff --git a/validation/linear/missing-return3.c b/validation/linear/missing-return3.c new file mode 100644 index 00000000..b32e5eea --- /dev/null +++ b/validation/linear/missing-return3.c @@ -0,0 +1,18 @@ +static int foo(int a) +{ + if (a) + return; +} + +static void ref(void) +{ +} + +/* + * check-name: missing-return3 + * check-command: sparse -vir -flinearize=last $file + * + * check-error-start +linear/missing-return3.c:4:17: error: return with no return value + * check-error-end + */ diff --git a/validation/linear/missing-return4.c b/validation/linear/missing-return4.c new file mode 100644 index 00000000..779893a0 --- /dev/null +++ b/validation/linear/missing-return4.c @@ -0,0 +1,14 @@ +static int foo(int a) +{ + int r = a; + r; +} + +/* + * check-name: missing-return4 + * check-command: test-linearize -Wno-decl $file + * + * check-error-ignore + * check-output-ignore + * check-output-contains: ret\\..*UNDEF + */ diff --git a/validation/linear/missing-return5.c b/validation/linear/missing-return5.c new file mode 100644 index 00000000..e5504a19 --- /dev/null +++ b/validation/linear/missing-return5.c @@ -0,0 +1,23 @@ +int foo(int p) +{ + if (p) + return 0; +} + +int bar(int p) +{ + if (p) + return 0; + p++; +} + +/* + * check-name: missing/undef return + * check-command: test-linearize -Wno-decl -fdump-ir=linearize $file + * + * check-output-ignore + * check-output-pattern(2): phi\\..*,.* + * check-output-pattern(2): phisrc\\..*\\$0 + * check-output-pattern(2): phisrc\\..*UNDEF + * check-output-excludes: ret\\..*\\$0 + */ diff --git a/validation/linear/phi-order01.c b/validation/linear/phi-order01.c new file mode 100644 index 00000000..0c4004fe --- /dev/null +++ b/validation/linear/phi-order01.c @@ -0,0 +1,16 @@ +int fun(void); + +static int foo(int a) +{ + return a && fun(); +} + +static int bar(int a) +{ + return a || fun(); +} + +/* + * check-name: phi-order01 + * check-command: sparse -vir -flinearize=last $file + */ diff --git a/validation/linear/phi-order02.c b/validation/linear/phi-order02.c new file mode 100644 index 00000000..d217ae45 --- /dev/null +++ b/validation/linear/phi-order02.c @@ -0,0 +1,16 @@ +int fun(void); + +static int foo(int a) { return 0 || fun(); } +static int bar(int a) { return 1 || fun(); } +static int baz(int a) { return 0 && fun(); } +static int qux(int a) { return 1 && fun(); } + +static int oof(int a) { return fun() || 1; } +static int rab(int a) { return fun() || 0; } +static int zab(int a) { return fun() && 1; } +static int xuq(int a) { return fun() && 0; } + +/* + * check-name: phi-order02 + * check-command: sparse -vir -flinearize=last $file + */ diff --git a/validation/linear/phi-order03.c b/validation/linear/phi-order03.c new file mode 100644 index 00000000..24ae10e7 --- /dev/null +++ b/validation/linear/phi-order03.c @@ -0,0 +1,8 @@ +int fun(void); + +static int foo(void) { return ((0 || fun()) && fun()); } + +/* + * check-name: phi-order03 + * check-command: sparse -vir -flinearize=last $file + */ diff --git a/validation/linear/phi-order04.c b/validation/linear/phi-order04.c new file mode 100644 index 00000000..7548537a --- /dev/null +++ b/validation/linear/phi-order04.c @@ -0,0 +1,12 @@ +static void foo(int *b) +{ + if (1) { + int c; + b = &c; + } +} + +/* + * check-name: phi-order04 + * check-command: sparse -vir -flinearize=last $file + */ |
