diff options
| -rw-r--r-- | lib.h | 5 | ||||
| -rw-r--r-- | linearize.c | 10 | ||||
| -rw-r--r-- | linearize.h | 2 | ||||
| -rw-r--r-- | parse.c | 15 | ||||
| -rw-r--r-- | simplify.c | 140 | ||||
| -rw-r--r-- | sparse-llvm.c | 75 | ||||
| -rw-r--r-- | validation/asm-bad0.c | 2 | ||||
| -rw-r--r-- | validation/bad-type-twice0.c | 3 | ||||
| -rw-r--r-- | validation/badtype2.c | 1 | ||||
| -rw-r--r-- | validation/badtype3.c | 1 | ||||
| -rw-r--r-- | validation/implicit-KR-arg-type1.c | 11 | ||||
| -rw-r--r-- | validation/linear/inline-definition.c | 30 | ||||
| -rw-r--r-- | validation/optim/set-uimm0.c | 14 | ||||
| -rw-r--r-- | validation/optim/simplify-neg-add-cte.c | 11 | ||||
| -rw-r--r-- | validation/optim/simplify-neg-not.c | 9 | ||||
| -rw-r--r-- | validation/optim/simplify-neg-sub.c | 9 | ||||
| -rw-r--r-- | validation/optim/simplify-not-add-cte.c | 11 | ||||
| -rw-r--r-- | validation/optim/simplify-not-neg.c | 9 | ||||
| -rw-r--r-- | validation/optim/simplify-not-sub-cte.c | 11 | ||||
| -rw-r--r-- | validation/optim/simplify-not-xor-cte.c | 11 |
20 files changed, 267 insertions, 113 deletions
@@ -204,6 +204,11 @@ static inline pseudo_t first_pseudo(struct pseudo_list *head) return first_ptr_list((struct ptr_list *)head); } +static inline struct symbol *first_symbol(struct symbol_list *head) +{ + return first_ptr_list((struct ptr_list *)head); +} + static inline void concat_symbol_list(struct symbol_list *from, struct symbol_list **to) { concat_ptr_list((struct ptr_list *)from, (struct ptr_list **)to); diff --git a/linearize.c b/linearize.c index 978d1e41..d9a3ac49 100644 --- a/linearize.c +++ b/linearize.c @@ -426,10 +426,10 @@ const char *show_instruction(struct instruction *insn) break; } case OP_LOAD: - buf += sprintf(buf, "%s <- %d[%s]", show_pseudo(insn->target), insn->offset, show_pseudo(insn->src)); + buf += sprintf(buf, "%s <- %lld[%s]", show_pseudo(insn->target), insn->offset, show_pseudo(insn->src)); break; case OP_STORE: - buf += sprintf(buf, "%s -> %d[%s]", show_pseudo(insn->target), insn->offset, show_pseudo(insn->src)); + buf += sprintf(buf, "%s -> %lld[%s]", show_pseudo(insn->target), insn->offset, show_pseudo(insn->src)); break; case OP_INLINED_CALL: case OP_CALL: { @@ -925,7 +925,7 @@ struct access_data { struct symbol *type; // ctype struct symbol *btype; // base type of bitfields pseudo_t address; // pseudo containing address .. - unsigned int offset; // byte offset + long long offset; // byte offset }; static int linearize_simple_address(struct entrypoint *ep, @@ -1520,8 +1520,6 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi } ctype = &fntype->ctype; - if (fntype->type == SYM_NODE) - fntype = fntype->ctype.base_type; add_symbol(&insn->fntypes, fntype); FOR_EACH_PTR(expr->args, arg) { @@ -2058,7 +2056,7 @@ static pseudo_t linearize_inlined_call(struct entrypoint *ep, struct statement * pseudo = linearize_fn_statement(ep, stmt); insn->target = pseudo; - use_pseudo(insn, symbol_pseudo(ep, stmt->inline_fn), &insn->func); + insn->func = symbol_pseudo(ep, stmt->inline_fn); bb = ep->active; if (!bb->insns) bb->pos = stmt->pos; diff --git a/linearize.h b/linearize.h index 76efd0b4..d8cbc3f3 100644 --- a/linearize.h +++ b/linearize.h @@ -117,7 +117,7 @@ struct instruction { }; struct /* memops */ { pseudo_t addr; /* alias .src */ - unsigned int offset; + long long offset; unsigned int is_volatile:1; }; struct /* binops and sel */ { @@ -2468,6 +2468,11 @@ static struct token *statement(struct token *token, struct statement **tree) warn_label_usage(stmt->pos, s->label_pos, s->ident); } s->stmt = stmt; + if (match_op(token, '}')) { + warning(token->pos, "statement expected after label"); + stmt->label_statement = alloc_statement(token->pos, STMT_NONE); + return token; + } return statement(token, &stmt->label_statement); } } @@ -2713,6 +2718,14 @@ static void declare_argument(struct symbol *sym, struct symbol *fn) sparse_error(sym->pos, "no identifier for function argument"); return; } + if (sym->ctype.base_type == &incomplete_ctype) { + sym->ctype.base_type = &int_ctype; + + if (Wimplicit_int) { + sparse_error(sym->pos, "missing type declaration for parameter '%s'", + show_ident(sym->ident)); + } + } bind_symbol(sym, sym->ident, NS_SYMBOL); } @@ -2804,7 +2817,7 @@ static void apply_k_r_types(struct symbol_list *argtypes, struct symbol *fn) goto match; } END_FOR_EACH_PTR(type); if (Wimplicit_int) { - sparse_error(arg->pos, "missing type declaration for parameter '%s'", + warning(arg->pos, "missing type declaration for parameter '%s'", show_ident(arg->ident)); } type = alloc_symbol(arg->pos, SYM_NODE); @@ -351,9 +351,9 @@ int kill_insn(struct instruction *insn, int force) case OP_CALL: if (!force) { /* a "pure" function can be killed too */ - if (!(insn->func->type == PSEUDO_SYM)) - return 0; - if (!(insn->func->sym->ctype.modifiers & MOD_PURE)) + struct symbol *fntype = first_symbol(insn->fntypes); + + if (!(fntype->ctype.modifiers & MOD_PURE)) return 0; } kill_use_list(insn->arguments); @@ -388,20 +388,6 @@ int kill_insn(struct instruction *insn, int force) return repeat_phase |= REPEAT_CSE; } -/// -// kill trivially dead instructions -static int dead_insn(struct instruction *insn, pseudo_t *src1, pseudo_t *src2, pseudo_t *src3) -{ - if (has_users(insn->target)) - return 0; - - insn->bb = NULL; - kill_use(src1); - kill_use(src2); - kill_use(src3); - return REPEAT_CSE; -} - static inline bool has_target(struct instruction *insn) { return opcode_table[insn->opcode].flags & OPF_TARGET; @@ -1173,6 +1159,36 @@ static int simplify_constant_rightside(struct instruction *insn) case OP_SET_NE: case OP_SET_EQ: return simplify_seteq_setne(insn, value); + case OP_SET_B: + if (!value) { // (x < 0) --> 0 + return replace_with_pseudo(insn, value_pseudo(0)); + } else if (value == 1) { // (x < 1) --> (x == 0) + insn->src2 = value_pseudo(0); + insn->opcode = OP_SET_EQ; + return REPEAT_CSE; + } + break; + case OP_SET_AE: + if (!value) { // (x >= 0) --> 1 + return replace_with_pseudo(insn, value_pseudo(1)); + } else if (value == 1) { // (x >= 1) --> (x != 0) + insn->src2 = value_pseudo(0); + insn->opcode = OP_SET_NE; + return REPEAT_CSE; + } + break; + case OP_SET_BE: + if (!value) { // (x <= 0) --> (x == 0) + insn->opcode = OP_SET_EQ; + return REPEAT_CSE; + } + break; + case OP_SET_A: + if (!value) { // (x > 0) --> (x != 0) + insn->opcode = OP_SET_NE; + return REPEAT_CSE; + } + break; } return 0; } @@ -1270,8 +1286,6 @@ static int simplify_binop_same_args(struct instruction *insn, pseudo_t arg) static int simplify_binop(struct instruction *insn) { - if (dead_insn(insn, &insn->src1, &insn->src2, NULL)) - return REPEAT_CSE; if (constant(insn->src1)) { if (constant(insn->src2)) return simplify_constant_binop(insn); @@ -1451,21 +1465,62 @@ static int simplify_constant_unop(struct instruction *insn) static int simplify_unop(struct instruction *insn) { - if (dead_insn(insn, &insn->src1, NULL, NULL)) - return REPEAT_CSE; - if (constant(insn->src1)) + struct instruction *def; + pseudo_t src = insn->src; + + if (constant(src)) return simplify_constant_unop(insn); switch (insn->opcode) { - struct instruction *def; - case OP_NOT: - if (DEF_OPCODE(def, insn->src) == OP_NOT) + switch (DEF_OPCODE(def, src)) { + case OP_ADD: + if (!constant(def->src2)) + break; + insn->opcode = OP_SUB; // ~(x + C) --> ~C - x + src = eval_unop(OP_NOT, insn->size, def->src2); + use_pseudo(insn, def->src1, &insn->src2); + return replace_pseudo(insn, &insn->src1, src); + case OP_NEG: + insn->opcode = OP_SUB; // ~(-x) --> x - 1 + insn->src2 = value_pseudo(1); + return replace_pseudo(insn, &insn->src1, def->src); + case OP_NOT: // ~(~x) --> x return replace_with_pseudo(insn, def->src); + case OP_SUB: + if (!constant(def->src1)) + break; + insn->opcode = OP_ADD; // ~(C - x) --> x + ~C + insn->src2 = eval_unop(OP_NOT, insn->size, def->src1); + return replace_pseudo(insn, &insn->src1, def->src2); + case OP_XOR: + if (!constant(def->src2)) + break; + insn->opcode = OP_XOR; // ~(x ^ C) --> x ^ ~C + insn->src2 = eval_unop(OP_NOT, insn->size, def->src2); + return replace_pseudo(insn, &insn->src1, def->src1); + } break; case OP_NEG: - if (DEF_OPCODE(def, insn->src) == OP_NEG) + switch (DEF_OPCODE(def, src)) { + case OP_ADD: + if (!constant(def->src2)) + break; + insn->opcode = OP_SUB; // -(x + C) --> (-C - x) + src = eval_unop(OP_NEG, insn->size, def->src2); + use_pseudo(insn, def->src1, &insn->src2); + return replace_pseudo(insn, &insn->src1, src); + case OP_NEG: // -(-x) --> x return replace_with_pseudo(insn, def->src); + case OP_NOT: + insn->opcode = OP_ADD; // -(~x) --> x + 1 + insn->src2 = value_pseudo(1); + return replace_pseudo(insn, &insn->src1, def->src); + case OP_SUB: + insn->opcode = OP_SUB; // -(x - y) --> y - x + use_pseudo(insn, def->src1, &insn->src2); + return replace_pseudo(insn, &insn->src1, def->src2); + } break; default: return 0; @@ -1543,16 +1598,11 @@ static int simplify_cast(struct instruction *insn) { unsigned long long mask; struct instruction *def; - pseudo_t src; + pseudo_t src = insn->src; pseudo_t val; int osize; int size; - if (dead_insn(insn, &insn->src, NULL, NULL)) - return REPEAT_CSE; - - src = insn->src; - /* A cast of a constant? */ if (constant(src)) return simplify_constant_unop(insn); @@ -1687,9 +1737,6 @@ static int simplify_select(struct instruction *insn) { pseudo_t cond, src1, src2; - if (dead_insn(insn, &insn->src1, &insn->src2, &insn->src3)) - return REPEAT_CSE; - cond = insn->src1; src1 = insn->src2; src2 = insn->src3; @@ -1861,6 +1908,10 @@ int simplify_instruction(struct instruction *insn) return 0; flags = opcode_table[insn->opcode].flags; + if (flags & OPF_TARGET) { + if (!has_users(insn->target)) + return kill_instruction(insn); + } if (flags & OPF_COMMU) canonicalize_commutative(insn) ; if (flags & OPF_COMPARE) @@ -1906,14 +1957,9 @@ int simplify_instruction(struct instruction *insn) case OP_SET_AE: break; case OP_LOAD: - if (!has_users(insn->target)) - return kill_instruction(insn); - /* fall-through */ case OP_STORE: return simplify_memop(insn); case OP_SYMADDR: - if (dead_insn(insn, &insn->src, NULL, NULL)) - return REPEAT_CSE | REPEAT_SYMBOL_CLEANUP; return replace_with_pseudo(insn, insn->src); case OP_SEXT: case OP_ZEXT: case OP_TRUNC: @@ -1923,30 +1969,18 @@ int simplify_instruction(struct instruction *insn) case OP_UCVTF: case OP_SCVTF: case OP_FCVTF: case OP_PTRCAST: - if (dead_insn(insn, &insn->src, NULL, NULL)) - return REPEAT_CSE; break; case OP_UTPTR: case OP_PTRTU: return replace_with_pseudo(insn, insn->src); case OP_SLICE: - if (dead_insn(insn, &insn->src, NULL, NULL)) - return REPEAT_CSE; break; case OP_SETVAL: case OP_SETFVAL: - if (dead_insn(insn, NULL, NULL, NULL)) - return REPEAT_CSE; break; case OP_PHI: - if (dead_insn(insn, NULL, NULL, NULL)) { - kill_use_list(insn->phi_list); - return REPEAT_CSE; - } return clean_up_phi(insn); case OP_PHISOURCE: - if (dead_insn(insn, &insn->phi_src, NULL, NULL)) - return REPEAT_CSE; break; case OP_SEL: return simplify_select(insn); @@ -1960,8 +1994,6 @@ int simplify_instruction(struct instruction *insn) case OP_FSUB: case OP_FMUL: case OP_FDIV: - if (dead_insn(insn, &insn->src1, &insn->src2, NULL)) - return REPEAT_CSE; break; } return 0; diff --git a/sparse-llvm.c b/sparse-llvm.c index c7a9fbb7..c984dc87 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -826,37 +826,14 @@ static void output_op_call(struct function *fn, struct instruction *insn) static void output_op_phisrc(struct function *fn, struct instruction *insn) { - LLVMValueRef v; - struct instruction *phi; - - assert(insn->target->priv == NULL); - - /* target = src */ - v = get_operand(fn, insn->type, insn->phi_src); - - FOR_EACH_PTR(insn->phi_users, phi) { - LLVMValueRef load, ptr; - - assert(phi->opcode == OP_PHI); - /* phi must be load from alloca */ - load = phi->target->priv; - assert(LLVMGetInstructionOpcode(load) == LLVMLoad); - ptr = LLVMGetOperand(load, 0); - /* store v to alloca */ - LLVMBuildStore(fn->builder, v, ptr); - } END_FOR_EACH_PTR(phi); + insn->src->priv = get_operand(fn, insn->type, insn->src); } static void output_op_phi(struct function *fn, struct instruction *insn) { - LLVMValueRef load = insn->target->priv; - - /* forward load */ - assert(LLVMGetInstructionOpcode(load) == LLVMLoad); - /* forward load has no parent block */ - assert(!LLVMGetInstructionParent(load)); - /* finalize load in current block */ - LLVMInsertIntoBuilder(fn->builder, load); + LLVMTypeRef dst_type = insn_symbol_type(insn); + + insn->target->priv = LLVMBuildPhi(fn->builder, dst_type, ""); } static void output_op_ptrcast(struct function *fn, struct instruction *insn) @@ -1161,30 +1138,11 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep) static int nr_bb; LLVMBasicBlockRef bbr; char bbname[32]; - struct instruction *insn; sprintf(bbname, "L%d", nr_bb++); bbr = LLVMAppendBasicBlock(function.fn, bbname); bb->priv = bbr; - - /* allocate alloca for each phi */ - FOR_EACH_PTR(bb->insns, insn) { - LLVMBasicBlockRef entrybbr; - LLVMTypeRef phi_type; - LLVMValueRef ptr; - - if (!insn->bb || insn->opcode != OP_PHI) - continue; - /* insert alloca into entry block */ - entrybbr = LLVMGetEntryBasicBlock(function.fn); - LLVMPositionBuilderAtEnd(function.builder, entrybbr); - phi_type = insn_symbol_type(insn); - ptr = LLVMBuildAlloca(function.builder, phi_type, ""); - /* emit forward load for phi */ - LLVMClearInsertionPosition(function.builder); - insn->target->priv = LLVMBuildLoad(function.builder, ptr, "phi"); - } END_FOR_EACH_PTR(insn); } END_FOR_EACH_PTR(bb); @@ -1194,6 +1152,31 @@ static void output_fn(LLVMModuleRef module, struct entrypoint *ep) output_bb(&function, bb); } END_FOR_EACH_PTR(bb); + + FOR_EACH_PTR(ep->bbs, bb) { // complete the OP_PHIs + struct instruction *insn; + + FOR_EACH_PTR(bb->insns, insn) { + pseudo_t phi; + + if (!insn->bb || insn->opcode != OP_PHI) + continue; + + FOR_EACH_PTR(insn->phi_list, phi) { + struct instruction *phisrc; + LLVMBasicBlockRef bref; + LLVMValueRef vref; + + if (phi == VOID) + continue; + + phisrc = phi->def; + bref = phisrc->bb->priv; + vref = phisrc->src->priv; + LLVMAddIncoming(insn->target->priv, &vref, &bref, 1); + } END_FOR_EACH_PTR(phi); + } END_FOR_EACH_PTR(insn); + } END_FOR_EACH_PTR(bb); } static LLVMValueRef output_data(LLVMModuleRef module, struct symbol *sym) diff --git a/validation/asm-bad0.c b/validation/asm-bad0.c index aa9bf28d..4ba78575 100644 --- a/validation/asm-bad0.c +++ b/validation/asm-bad0.c @@ -16,7 +16,7 @@ static void icons(void) asm("template" : [out] "=r" (var): [in] string (0)); } -static void oexpr(oid) +static void oexpr(void) { asm("template" : [out] "=" (var[) : [in] "r" (0)); } diff --git a/validation/bad-type-twice0.c b/validation/bad-type-twice0.c index 9e834d47..e7ec7b75 100644 --- a/validation/bad-type-twice0.c +++ b/validation/bad-type-twice0.c @@ -7,7 +7,6 @@ static int foo(a) * check-name: bad-type-twice0 * * check-error-start -bad-type-twice0.c:3:16: error: non-scalar type in conditional: -bad-type-twice0.c:3:16: incomplete type a +bad-type-twice0.c:1:16: error: missing type declaration for parameter 'a' * check-error-end */ diff --git a/validation/badtype2.c b/validation/badtype2.c index 49fec87c..173dbfda 100644 --- a/validation/badtype2.c +++ b/validation/badtype2.c @@ -18,6 +18,7 @@ badtype2.c:2:14: error: got bar badtype2.c:3:14: error: Expected ; at end of declaration badtype2.c:3:14: error: got foo badtype2.c:6:3: error: Trying to use reserved word 'switch' as identifier +badtype2.c:6:11: error: missing type declaration for parameter 'p' badtype2.c:7:3: error: not in switch scope badtype2.c:10:1: error: Expected ; at the end of type declaration badtype2.c:10:1: error: got } diff --git a/validation/badtype3.c b/validation/badtype3.c index 20f346c5..c111d94e 100644 --- a/validation/badtype3.c +++ b/validation/badtype3.c @@ -16,6 +16,7 @@ badtype3.c:2:18: warning: identifier list not in definition badtype3.c:2:24: error: Expected ) in function declarator badtype3.c:2:24: error: got , badtype3.c:5:3: error: Trying to use reserved word 'while' as identifier +badtype3.c:5:10: error: missing type declaration for parameter 'cur' badtype3.c:7:7: error: break/continue not in iterator scope badtype3.c:9:3: error: Trying to use reserved word 'return' as identifier badtype3.c:9:10: error: Expected ; at end of declaration diff --git a/validation/implicit-KR-arg-type1.c b/validation/implicit-KR-arg-type1.c index fe199ef5..c7eb39ae 100644 --- a/validation/implicit-KR-arg-type1.c +++ b/validation/implicit-KR-arg-type1.c @@ -1,16 +1,23 @@ -int foo(a, b) +static int foo(a, b) int a; { if (b) return a; } +static int bar(a) +{ + if (a) + return a; +} + /* * check-name: implicit-KR-arg-type1 * check-command: sparse -Wold-style-definition -Wimplicit-int $file * * check-error-start implicit-KR-arg-type1.c:2:9: warning: non-ANSI definition of function 'foo' -implicit-KR-arg-type1.c:1:12: error: missing type declaration for parameter 'b' +implicit-KR-arg-type1.c:1:19: warning: missing type declaration for parameter 'b' +implicit-KR-arg-type1.c:8:16: error: missing type declaration for parameter 'a' * check-error-end */ diff --git a/validation/linear/inline-definition.c b/validation/linear/inline-definition.c new file mode 100644 index 00000000..2918bd5d --- /dev/null +++ b/validation/linear/inline-definition.c @@ -0,0 +1,30 @@ +extern void use(void *); + +static inline int inl0(int a); +static inline int inl1(int a); + +static inline int inl0(int a) +{ + return a; +} + +void foo(void) +{ + use(inl0); + use(inl1); +} + +static inline int inl1(int a) +{ + return a; +} + +/* + * check-name: inline-definition + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-contains: inl0: + * check-output-contains: inl1: + */ diff --git a/validation/optim/set-uimm0.c b/validation/optim/set-uimm0.c new file mode 100644 index 00000000..ded8fc82 --- /dev/null +++ b/validation/optim/set-uimm0.c @@ -0,0 +1,14 @@ +static _Bool setlt0(unsigned int a) { return (a < 0u) == 0; } +static _Bool setge0(unsigned int a) { return (a >= 0u) == 1; } +static _Bool setle0(unsigned int a) { return (a <= 0u) == (a == 0); } +static _Bool setgt0(unsigned int a) { return (a > 0u) == (a != 0); } +static _Bool setlt1(unsigned int a) { return (a < 1u) == (a == 0); } +static _Bool setge1(unsigned int a) { return (a >= 1u) == (a != 0); } + +/* + * check-name: set-uimm0 + * check-command: test-linearize $file + * + * check-output-ignore + * check-output-pattern(6): ret\\.1 *\\$1 + */ diff --git a/validation/optim/simplify-neg-add-cte.c b/validation/optim/simplify-neg-add-cte.c new file mode 100644 index 00000000..a02c474f --- /dev/null +++ b/validation/optim/simplify-neg-add-cte.c @@ -0,0 +1,11 @@ +#define C 3 + +int foo(int x) { return -(x + C) == (-3 - x); } + +/* + * check-name: simplify-neg-add-cte + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: ret\\..*\\$1 + */ diff --git a/validation/optim/simplify-neg-not.c b/validation/optim/simplify-neg-not.c new file mode 100644 index 00000000..e92352cf --- /dev/null +++ b/validation/optim/simplify-neg-not.c @@ -0,0 +1,9 @@ +int foo(int x) { return -(~x) == x + 1; } + +/* + * check-name: simplify-neg-not + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: ret\\..*\\$1 + */ diff --git a/validation/optim/simplify-neg-sub.c b/validation/optim/simplify-neg-sub.c new file mode 100644 index 00000000..9a824f09 --- /dev/null +++ b/validation/optim/simplify-neg-sub.c @@ -0,0 +1,9 @@ +int foo(int x, int y) { return -(x - y) == (y - x); } + +/* + * check-name: simplify-neg-sub + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: ret\\..*\\$1 + */ diff --git a/validation/optim/simplify-not-add-cte.c b/validation/optim/simplify-not-add-cte.c new file mode 100644 index 00000000..6594012b --- /dev/null +++ b/validation/optim/simplify-not-add-cte.c @@ -0,0 +1,11 @@ +#define C 3 + +int foo(int x) { return ~(x + C) == (~C - x); } + +/* + * check-name: simplify-not-add-cte + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: ret\\..*\\$1 + */ diff --git a/validation/optim/simplify-not-neg.c b/validation/optim/simplify-not-neg.c new file mode 100644 index 00000000..3fd8400d --- /dev/null +++ b/validation/optim/simplify-not-neg.c @@ -0,0 +1,9 @@ +int foo(int x) { return ~(-x) == (x - 1); } + +/* + * check-name: simplify-not-neg + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: ret\\..*\\$1 + */ diff --git a/validation/optim/simplify-not-sub-cte.c b/validation/optim/simplify-not-sub-cte.c new file mode 100644 index 00000000..1ea73ece --- /dev/null +++ b/validation/optim/simplify-not-sub-cte.c @@ -0,0 +1,11 @@ +#define C 3 + +int foo(int x) { return ~(C - x) == (x + ~C); } + +/* + * check-name: simplify-not-sub-cte + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: ret\\..*\\$1 + */ diff --git a/validation/optim/simplify-not-xor-cte.c b/validation/optim/simplify-not-xor-cte.c new file mode 100644 index 00000000..c3c803b3 --- /dev/null +++ b/validation/optim/simplify-not-xor-cte.c @@ -0,0 +1,11 @@ +#define C 3 + +int foo(int x) { return ~(x ^ C) == (x ^ ~C); } + +/* + * check-name: simplify-not-xor-cte + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-contains: ret\\..*\\$1 + */ |
