aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-08-06 09:54:56 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-08-07 15:50:06 +0200
commit51940ca1bb0a756349f1d729d34e0a166a6bd2d5 (patch)
tree23fd3edb21fdc378e592447252d5f2f3517348f5
parentc22d39ec3768b210ba5ab6110c5f311980f8fb1a (diff)
parent6da6517086e523f25cef070f9a89105f43147896 (diff)
downloadsparse-dev-51940ca1bb0a756349f1d729d34e0a166a6bd2d5.tar.gz
Merge branch 'fix-logical-extra' into tip
* fix a few bugs related to the linearization of logical expressions * simplify those logical expressions.
-rw-r--r--linearize.c52
-rw-r--r--simplify.c53
-rw-r--r--validation/cast-kinds-check.c4
-rw-r--r--validation/cast-weirds.c4
-rw-r--r--validation/linear/bitfield-size.c12
-rw-r--r--validation/linear/call-complex-pointer.c10
-rw-r--r--validation/linear/logical.c259
-rw-r--r--validation/loop-linearization.c44
-rw-r--r--validation/optim/bool-simplify.c15
-rw-r--r--validation/optim/call-inlined.c4
-rw-r--r--validation/optim/mask1-setne0.c28
-rw-r--r--validation/optim/setcc-mask.c18
-rw-r--r--validation/optim/setne0-sext.c9
-rw-r--r--validation/optim/setne0-trunc.c9
-rw-r--r--validation/optim/setne0-zext.c9
-rw-r--r--validation/optim/trunc-seteq0.c18
-rw-r--r--validation/optim/trunc-setne0.c20
17 files changed, 509 insertions, 59 deletions
diff --git a/linearize.c b/linearize.c
index 016b853b..c2010c4b 100644
--- a/linearize.c
+++ b/linearize.c
@@ -972,13 +972,14 @@ static pseudo_t linearize_bitfield_insert(struct entrypoint *ep,
unsigned int shift = ctype->bit_offset;
unsigned int size = ctype->bit_size;
unsigned long long mask = ((1ULL << size) - 1);
+ unsigned long long smask= bits_mask(btype->bit_size);
val = add_cast(ep, btype, ctype, OP_ZEXT, val);
if (shift) {
val = add_binary_op(ep, btype, OP_SHL, val, value_pseudo(shift));
mask <<= shift;
}
- ori = add_binary_op(ep, btype, OP_AND, ori, value_pseudo(~mask));
+ ori = add_binary_op(ep, btype, OP_AND, ori, value_pseudo(~mask & smask));
val = add_binary_op(ep, btype, OP_OR, ori, val);
return val;
@@ -1313,6 +1314,7 @@ static int get_cast_opcode(struct symbol *dst, struct symbol *src)
static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *from, struct symbol *to)
{
+ const struct position pos = current_pos;
pseudo_t result;
struct instruction *insn;
int opcode;
@@ -1333,7 +1335,7 @@ static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *
if (src == value_pseudo(0))
break;
if (Wint_to_pointer_cast)
- warning(to->pos, "non size-preserving integer to pointer cast");
+ warning(pos, "non size-preserving integer to pointer cast");
src = cast_pseudo(ep, src, from, size_t_ctype);
from = size_t_ctype;
break;
@@ -1341,7 +1343,7 @@ static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *
if (from->bit_size == to->bit_size)
break;
if (Wpointer_to_int_cast)
- warning(to->pos, "non size-preserving pointer to integer cast");
+ warning(pos, "non size-preserving pointer to integer cast");
src = cast_pseudo(ep, src, from, size_t_ctype);
return cast_pseudo(ep, src, size_t_ctype, to);
case OP_BADOP:
@@ -1376,8 +1378,12 @@ static inline pseudo_t add_convert_to_bool(struct entrypoint *ep, pseudo_t src,
pseudo_t zero;
int op;
+ if (!type || src == VOID)
+ return VOID;
if (is_bool_type(type))
return src;
+ if (src->type == PSEUDO_VAL && (src->value == 0 || src->value == 1))
+ return src;
if (is_float_type(type)) {
zero = add_setfval(ep, type, 0.0);
op = map_opcode(OP_SET_NE, type);
@@ -1642,13 +1648,39 @@ static pseudo_t linearize_conditional(struct entrypoint *ep, struct expression *
static pseudo_t linearize_logical(struct entrypoint *ep, struct expression *expr)
{
- struct expression *shortcut;
+ struct basic_block *other, *merge;
+ pseudo_t phi1, phi2;
- shortcut = alloc_const_expression(expr->pos, expr->op == SPECIAL_LOGICAL_OR);
- shortcut->ctype = expr->ctype;
- if (expr->op == SPECIAL_LOGICAL_OR)
- return linearize_conditional(ep, expr, expr->left, shortcut, expr->right);
- return linearize_conditional(ep, expr, expr->left, expr->right, shortcut);
+ if (!ep->active || !expr->left || !expr->right)
+ return VOID;
+
+ other = alloc_basic_block(ep, expr->right->pos);
+ merge = alloc_basic_block(ep, expr->pos);
+
+ 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);
+ } 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);
+ }
+
+ set_activeblock(ep, merge);
+ return add_join_conditional(ep, expr, phi1, phi2);
}
static pseudo_t linearize_compare(struct entrypoint *ep, struct expression *expr)
@@ -1704,7 +1736,7 @@ static pseudo_t linearize_cond_branch(struct entrypoint *ep, struct expression *
return linearize_cond_branch(ep, expr->unop, bb_false, bb_true);
/* fall through */
default: {
- cond = linearize_expression(ep, expr);
+ cond = linearize_expression_to_bool(ep, expr);
add_branch(ep, expr, cond, bb_true, bb_false);
return VOID;
diff --git a/simplify.c b/simplify.c
index 57e90b9b..4dfcf198 100644
--- a/simplify.c
+++ b/simplify.c
@@ -690,6 +690,7 @@ static int simplify_seteq_setne(struct instruction *insn, long long value)
{
pseudo_t old = insn->src1;
struct instruction *def;
+ unsigned osize;
int inverse;
int opcode;
@@ -703,7 +704,7 @@ static int simplify_seteq_setne(struct instruction *insn, long long value)
return 0;
inverse = (insn->opcode == OP_SET_NE) == value;
- if (!inverse && def->size == 1) {
+ if (!inverse && def->size == 1 && insn->size == 1) {
// Replace:
// setne %r <- %s, $0
// or:
@@ -713,6 +714,16 @@ static int simplify_seteq_setne(struct instruction *insn, long long value)
}
opcode = def->opcode;
switch (opcode) {
+ case OP_AND:
+ if (inverse)
+ break;
+ if (def->size != insn->size)
+ break;
+ if (def->src2->type != PSEUDO_VAL)
+ break;
+ if (def->src2->value != 1)
+ break;
+ return replace_with_pseudo(insn, old);
case OP_FPCMP ... OP_BINCMP_END:
// Convert:
// setcc.n %t <- %a, %b
@@ -739,6 +750,22 @@ static int simplify_seteq_setne(struct instruction *insn, long long value)
// setne.1 %s <- %a, $0
// and same for setne/eq ... 0/1
return replace_pseudo(insn, &insn->src1, def->src);
+ case OP_TRUNC:
+ if (nbr_users(old) > 1)
+ break;
+ // convert
+ // trunc.n %s <- (o) %a
+ // setne.m %r <- %s, $0
+ // into:
+ // and.o %s <- %a, $((1 << o) - 1)
+ // setne.m %r <- %s, $0
+ // and same for setne/eq ... 0/1
+ osize = def->size;
+ def->opcode = OP_AND;
+ def->type = def->orig_type;
+ def->size = def->type->bit_size;
+ def->src2 = value_pseudo(bits_mask(osize));
+ return REPEAT_CSE;
}
return 0;
}
@@ -752,8 +779,13 @@ static int simplify_constant_mask(struct instruction *insn, unsigned long long m
int osize;
switch (DEF_OPCODE(def, old)) {
+ case OP_FPCMP ... OP_BINCMP_END:
+ osize = 1;
+ goto oldsize;
case OP_ZEXT:
osize = def->orig_type->bit_size;
+ /* fall through */
+ oldsize:
omask = (1ULL << osize) - 1;
nmask = mask & omask;
if (nmask == omask)
@@ -1162,6 +1194,25 @@ static int simplify_cast(struct instruction *insn)
return REPEAT_CSE;
}
break;
+ case OP_FPCMP ... OP_BINCMP_END:
+ switch (insn->opcode) {
+ case OP_SEXT:
+ if (insn->size == 1)
+ break;
+ /* fall through */
+ case OP_ZEXT:
+ case OP_TRUNC:
+ // simplify:
+ // setcc.n %t <- %a, %b
+ // zext.m %r <- (n) %t
+ // into:
+ // setcc.m %r <- %a, %b
+ // and same for s/zext/trunc/
+ insn->opcode = def->opcode;
+ use_pseudo(insn, def->src2, &insn->src2);
+ return replace_pseudo(insn, &insn->src1, def->src1);
+ }
+ break;
case OP_TRUNC:
osize = def->orig_type->bit_size;
if (insn->opcode == OP_ZEXT && size == osize) {
diff --git a/validation/cast-kinds-check.c b/validation/cast-kinds-check.c
index b50ddd24..7eb1ca1c 100644
--- a/validation/cast-kinds-check.c
+++ b/validation/cast-kinds-check.c
@@ -13,7 +13,7 @@ optim/cast-kinds.c:12:48: warning: cast drops bits
optim/cast-kinds.c:13:50: warning: cast drops bits
optim/cast-kinds.c:14:49: warning: cast drops bits
optim/cast-kinds.c:15:48: warning: cast drops bits
-optim/cast-kinds.c:37:42: warning: non size-preserving integer to pointer cast
-optim/cast-kinds.c:38:44: warning: non size-preserving integer to pointer cast
+optim/cast-kinds.c:37:48: warning: non size-preserving integer to pointer cast
+optim/cast-kinds.c:38:50: warning: non size-preserving integer to pointer cast
* check-error-end
*/
diff --git a/validation/cast-weirds.c b/validation/cast-weirds.c
index 01ccc473..7d028882 100644
--- a/validation/cast-weirds.c
+++ b/validation/cast-weirds.c
@@ -12,7 +12,7 @@ static void * uint_2_vptr(uint a) { return (void *)a; }
* check-command: sparse -m64 $file
*
* check-error-start
-cast-weirds.c:4:42: warning: non size-preserving integer to pointer cast
-cast-weirds.c:5:44: warning: non size-preserving integer to pointer cast
+cast-weirds.c:4:48: warning: non size-preserving integer to pointer cast
+cast-weirds.c:5:50: warning: non size-preserving integer to pointer cast
* check-error-end
*/
diff --git a/validation/linear/bitfield-size.c b/validation/linear/bitfield-size.c
index 963f6e28..7f9725f9 100644
--- a/validation/linear/bitfield-size.c
+++ b/validation/linear/bitfield-size.c
@@ -52,7 +52,7 @@ upostinc:
add.3 %r4 <- %r3, $1
load.32 %r5 <- 0[%r1]
zext.32 %r6 <- (3) %r4
- and.32 %r7 <- %r5, $-8
+ and.32 %r7 <- %r5, $0xfffffff8
or.32 %r8 <- %r7, %r6
store.32 %r8 -> 0[%r1]
zext.32 %r9 <- (3) %r3
@@ -74,7 +74,7 @@ upreinc:
add.3 %r14 <- %r13, $1
load.32 %r15 <- 0[%r11]
zext.32 %r16 <- (3) %r14
- and.32 %r17 <- %r15, $-8
+ and.32 %r17 <- %r15, $0xfffffff8
or.32 %r18 <- %r17, %r16
store.32 %r18 -> 0[%r11]
zext.32 %r19 <- (3) %r14
@@ -97,7 +97,7 @@ ucpy:
load.64 %r24 <- 0[d]
load.32 %r25 <- 0[%r24]
zext.32 %r26 <- (3) %r23
- and.32 %r27 <- %r25, $-8
+ and.32 %r27 <- %r25, $0xfffffff8
or.32 %r28 <- %r27, %r26
store.32 %r28 -> 0[%r24]
br .L5
@@ -116,7 +116,7 @@ spostinc:
add.3 %r32 <- %r31, $1
load.32 %r33 <- 0[%r29]
zext.32 %r34 <- (3) %r32
- and.32 %r35 <- %r33, $-8
+ and.32 %r35 <- %r33, $0xfffffff8
or.32 %r36 <- %r35, %r34
store.32 %r36 -> 0[%r29]
zext.32 %r37 <- (3) %r31
@@ -138,7 +138,7 @@ spreinc:
add.3 %r42 <- %r41, $1
load.32 %r43 <- 0[%r39]
zext.32 %r44 <- (3) %r42
- and.32 %r45 <- %r43, $-8
+ and.32 %r45 <- %r43, $0xfffffff8
or.32 %r46 <- %r45, %r44
store.32 %r46 -> 0[%r39]
zext.32 %r47 <- (3) %r42
@@ -161,7 +161,7 @@ scpy:
load.64 %r52 <- 0[d]
load.32 %r53 <- 0[%r52]
zext.32 %r54 <- (3) %r51
- and.32 %r55 <- %r53, $-8
+ and.32 %r55 <- %r53, $0xfffffff8
or.32 %r56 <- %r55, %r54
store.32 %r56 -> 0[%r52]
br .L11
diff --git a/validation/linear/call-complex-pointer.c b/validation/linear/call-complex-pointer.c
index ea8232f1..dc0ab07b 100644
--- a/validation/linear/call-complex-pointer.c
+++ b/validation/linear/call-complex-pointer.c
@@ -18,14 +18,14 @@ foo:
br .L4
.L3:
- ptrcast.64 %r5 <- (64) %arg3
- phisrc.64 %phi2 <- %r5
+ ptrcast.64 %r6 <- (64) %arg3
+ phisrc.64 %phi2 <- %r6
br .L4
.L4:
- phi.64 %r6 <- %phi1, %phi2
- call.32 %r7 <- %r6, %arg4
- ret.32 %r7
+ phi.64 %r7 <- %phi1, %phi2
+ call.32 %r8 <- %r7, %arg4
+ ret.32 %r8
* check-output-end
diff --git a/validation/linear/logical.c b/validation/linear/logical.c
new file mode 100644
index 00000000..148ad427
--- /dev/null
+++ b/validation/linear/logical.c
@@ -0,0 +1,259 @@
+struct S {
+ int :1;
+ signed int s:2;
+ unsigned int u:3;
+ long l;
+ double d;
+};
+
+int os(int i, struct S *b) { return i || b->s; }
+int ou(int i, struct S *b) { return i || b->u; }
+int ol(int i, struct S *b) { return i || b->l; }
+int od(int i, struct S *b) { return i || b->d; }
+
+int as(int i, struct S *b) { return i && b->s; }
+int au(int i, struct S *b) { return i && b->u; }
+int al(int i, struct S *b) { return i && b->l; }
+int ad(int i, struct S *b) { return i && b->d; }
+
+/*
+ * check-name: logical
+ * check-command: test-linearize -m64 -fdump-ir -Wno-decl $file
+ *
+ * check-output-start
+os:
+.L0:
+ <entry-point>
+ store.32 %arg1 -> 0[i]
+ store.64 %arg2 -> 0[b]
+ phisrc.32 %phi1 <- $1
+ load.32 %r1 <- 0[i]
+ setne.1 %r2 <- %r1, $0
+ cbr %r2, .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
+ br .L3
+
+.L3:
+ phi.32 %r9 <- %phi1, %phi2
+ phisrc.32 %phi3(return) <- %r9
+ br .L1
+
+.L1:
+ phi.32 %r10 <- %phi3(return)
+ ret.32 %r10
+
+
+ou:
+.L4:
+ <entry-point>
+ store.32 %arg1 -> 0[i]
+ store.64 %arg2 -> 0[b]
+ phisrc.32 %phi5 <- $1
+ load.32 %r11 <- 0[i]
+ setne.1 %r12 <- %r11, $0
+ cbr %r12, .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 %phi6 <- %r18
+ br .L7
+
+.L7:
+ phi.32 %r19 <- %phi5, %phi6
+ phisrc.32 %phi7(return) <- %r19
+ br .L5
+
+.L5:
+ phi.32 %r20 <- %phi7(return)
+ ret.32 %r20
+
+
+ol:
+.L8:
+ <entry-point>
+ store.32 %arg1 -> 0[i]
+ store.64 %arg2 -> 0[b]
+ phisrc.32 %phi9 <- $1
+ load.32 %r21 <- 0[i]
+ setne.1 %r22 <- %r21, $0
+ cbr %r22, .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 %phi10 <- %r26
+ br .L11
+
+.L11:
+ phi.32 %r27 <- %phi9, %phi10
+ phisrc.32 %phi11(return) <- %r27
+ br .L9
+
+.L9:
+ phi.32 %r28 <- %phi11(return)
+ ret.32 %r28
+
+
+od:
+.L12:
+ <entry-point>
+ store.32 %arg1 -> 0[i]
+ store.64 %arg2 -> 0[b]
+ phisrc.32 %phi13 <- $1
+ load.32 %r29 <- 0[i]
+ setne.1 %r30 <- %r29, $0
+ cbr %r30, .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 %phi14 <- %r35
+ br .L15
+
+.L15:
+ phi.32 %r36 <- %phi13, %phi14
+ phisrc.32 %phi15(return) <- %r36
+ br .L13
+
+.L13:
+ phi.32 %r37 <- %phi15(return)
+ ret.32 %r37
+
+
+as:
+.L16:
+ <entry-point>
+ store.32 %arg1 -> 0[i]
+ store.64 %arg2 -> 0[b]
+ phisrc.32 %phi17 <- $0
+ load.32 %r38 <- 0[i]
+ setne.1 %r39 <- %r38, $0
+ cbr %r39, .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 %phi18 <- %r45
+ br .L19
+
+.L19:
+ phi.32 %r46 <- %phi18, %phi17
+ phisrc.32 %phi19(return) <- %r46
+ br .L17
+
+.L17:
+ phi.32 %r47 <- %phi19(return)
+ ret.32 %r47
+
+
+au:
+.L20:
+ <entry-point>
+ store.32 %arg1 -> 0[i]
+ store.64 %arg2 -> 0[b]
+ phisrc.32 %phi21 <- $0
+ load.32 %r48 <- 0[i]
+ setne.1 %r49 <- %r48, $0
+ cbr %r49, .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 %phi22 <- %r55
+ br .L23
+
+.L23:
+ phi.32 %r56 <- %phi22, %phi21
+ phisrc.32 %phi23(return) <- %r56
+ br .L21
+
+.L21:
+ phi.32 %r57 <- %phi23(return)
+ ret.32 %r57
+
+
+al:
+.L24:
+ <entry-point>
+ store.32 %arg1 -> 0[i]
+ store.64 %arg2 -> 0[b]
+ phisrc.32 %phi25 <- $0
+ load.32 %r58 <- 0[i]
+ setne.1 %r59 <- %r58, $0
+ cbr %r59, .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 %phi26 <- %r63
+ br .L27
+
+.L27:
+ phi.32 %r64 <- %phi26, %phi25
+ phisrc.32 %phi27(return) <- %r64
+ br .L25
+
+.L25:
+ phi.32 %r65 <- %phi27(return)
+ ret.32 %r65
+
+
+ad:
+.L28:
+ <entry-point>
+ store.32 %arg1 -> 0[i]
+ store.64 %arg2 -> 0[b]
+ phisrc.32 %phi29 <- $0
+ load.32 %r66 <- 0[i]
+ setne.1 %r67 <- %r66, $0
+ cbr %r67, .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 %phi30 <- %r72
+ br .L31
+
+.L31:
+ phi.32 %r73 <- %phi30, %phi29
+ phisrc.32 %phi31(return) <- %r73
+ br .L29
+
+.L29:
+ phi.32 %r74 <- %phi31(return)
+ ret.32 %r74
+
+
+ * check-output-end
+ */
diff --git a/validation/loop-linearization.c b/validation/loop-linearization.c
index 25c6dfb8..051e0453 100644
--- a/validation/loop-linearization.c
+++ b/validation/loop-linearization.c
@@ -56,8 +56,8 @@ ffor:
br .L7
.L2:
- add.32 %r7 <- %r1(i), $1
- phisrc.32 %phi6(i) <- %r7
+ add.32 %r8 <- %r1(i), $1
+ phisrc.32 %phi6(i) <- %r8
br .L4
.L3:
@@ -65,8 +65,8 @@ ffor:
br .L7
.L7:
- phi.32 %r5 <- %phi1(return), %phi2(return)
- ret.32 %r5
+ phi.32 %r6 <- %phi1(return), %phi2(return)
+ ret.32 %r6
fwhile:
@@ -76,21 +76,21 @@ fwhile:
br .L12
.L12:
- phi.32 %r8(i) <- %phi11(i), %phi12(i)
- setlt.32 %r9 <- %r8(i), $10
- cbr %r9, .L9, .L11
+ phi.32 %r9(i) <- %phi11(i), %phi12(i)
+ setlt.32 %r10 <- %r9(i), $10
+ cbr %r10, .L9, .L11
.L9:
- call.32 %r11 <- p, %r8(i)
- cbr %r11, .L14, .L13
+ call.32 %r12 <- p, %r9(i)
+ cbr %r12, .L14, .L13
.L13:
phisrc.32 %phi7(return) <- $0
br .L15
.L14:
- add.32 %r14 <- %r8(i), $1
- phisrc.32 %phi12(i) <- %r14
+ add.32 %r16 <- %r9(i), $1
+ phisrc.32 %phi12(i) <- %r16
br .L12
.L11:
@@ -98,8 +98,8 @@ fwhile:
br .L15
.L15:
- phi.32 %r12 <- %phi7(return), %phi8(return)
- ret.32 %r12
+ phi.32 %r14 <- %phi7(return), %phi8(return)
+ ret.32 %r14
fdo:
@@ -109,27 +109,27 @@ fdo:
br .L17
.L17:
- phi.32 %r15(i) <- %phi16(i), %phi17(i)
- call.32 %r16 <- p, %r15(i)
- cbr %r16, .L18, .L20
+ phi.32 %r17(i) <- %phi16(i), %phi17(i)
+ call.32 %r18 <- p, %r17(i)
+ cbr %r18, .L18, .L20
.L20:
phisrc.32 %phi13(return) <- $0
br .L22
.L18:
- add.32 %r19 <- %r15(i), $1
- setlt.32 %r20 <- %r15(i), $10
- phisrc.32 %phi17(i) <- %r19
- cbr %r20, .L17, .L19
+ add.32 %r22 <- %r17(i), $1
+ setlt.32 %r23 <- %r17(i), $10
+ phisrc.32 %phi17(i) <- %r22
+ cbr %r23, .L17, .L19
.L19:
phisrc.32 %phi14(return) <- $1
br .L22
.L22:
- phi.32 %r17 <- %phi13(return), %phi14(return)
- ret.32 %r17
+ phi.32 %r20 <- %phi13(return), %phi14(return)
+ ret.32 %r20
* check-output-end
diff --git a/validation/optim/bool-simplify.c b/validation/optim/bool-simplify.c
index 68aabb78..fe8ce88b 100644
--- a/validation/optim/bool-simplify.c
+++ b/validation/optim/bool-simplify.c
@@ -43,17 +43,15 @@ and_0:
and_1:
.L2:
<entry-point>
- setne.1 %r8 <- %arg1, $0
- zext.32 %r11 <- (1) %r8
- ret.32 %r11
+ setne.32 %r9 <- %arg1, $0
+ ret.32 %r9
or_0:
.L4:
<entry-point>
- setne.1 %r14 <- %arg1, $0
- zext.32 %r17 <- (1) %r14
- ret.32 %r17
+ setne.32 %r14 <- %arg1, $0
+ ret.32 %r14
or_1:
@@ -65,9 +63,8 @@ or_1:
and_2:
.L8:
<entry-point>
- setne.1 %r26 <- %arg1, $0
- zext.32 %r29 <- (1) %r26
- ret.32 %r29
+ setne.32 %r25 <- %arg1, $0
+ ret.32 %r25
or_2:
diff --git a/validation/optim/call-inlined.c b/validation/optim/call-inlined.c
index 00698a4b..f21b3294 100644
--- a/validation/optim/call-inlined.c
+++ b/validation/optim/call-inlined.c
@@ -22,8 +22,8 @@ int foo(int a, int b, int p)
foo:
.L0:
<entry-point>
- select.32 %r9 <- %arg3, %arg3, $0
- ret.32 %r9
+ select.32 %r10 <- %arg3, %arg3, $0
+ ret.32 %r10
* check-output-end
diff --git a/validation/optim/mask1-setne0.c b/validation/optim/mask1-setne0.c
new file mode 100644
index 00000000..1e599dc8
--- /dev/null
+++ b/validation/optim/mask1-setne0.c
@@ -0,0 +1,28 @@
+struct s {
+ unsigned i:1;
+};
+
+int foo(struct s x)
+{
+ unsigned int i = x.i;
+
+ if (i == 0)
+ return 1;
+ else if (i == 1)
+ return 1;
+ return 0;
+}
+
+/*
+ * check-name: mask1-setne0
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-start
+foo:
+.L0:
+ <entry-point>
+ ret.32 $1
+
+
+ * check-output-end
+ */
diff --git a/validation/optim/setcc-mask.c b/validation/optim/setcc-mask.c
new file mode 100644
index 00000000..5d271788
--- /dev/null
+++ b/validation/optim/setcc-mask.c
@@ -0,0 +1,18 @@
+int foo (int a)
+{
+ return ((a == 0) & 1) == (a == 0);
+}
+
+/*
+ * check-name: setcc-mask
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-start
+foo:
+.L0:
+ <entry-point>
+ ret.32 $1
+
+
+ * check-output-end
+ */
diff --git a/validation/optim/setne0-sext.c b/validation/optim/setne0-sext.c
new file mode 100644
index 00000000..4167979b
--- /dev/null
+++ b/validation/optim/setne0-sext.c
@@ -0,0 +1,9 @@
+long foo(int a) { return a != 0; }
+
+/*
+ * check-name: setne0-sext
+ * check-command: test-linearize -m64 -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-excludes: sext\\.
+ */
diff --git a/validation/optim/setne0-trunc.c b/validation/optim/setne0-trunc.c
new file mode 100644
index 00000000..6c5494ec
--- /dev/null
+++ b/validation/optim/setne0-trunc.c
@@ -0,0 +1,9 @@
+char foo(int a) { return a != 0; }
+
+/*
+ * check-name: setne0-trunc
+ * check-command: test-linearize -m64 -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-excludes: trunc\\.
+ */
diff --git a/validation/optim/setne0-zext.c b/validation/optim/setne0-zext.c
new file mode 100644
index 00000000..8a074f03
--- /dev/null
+++ b/validation/optim/setne0-zext.c
@@ -0,0 +1,9 @@
+unsigned long foo(int a) { return (unsigned int) (a != 0); }
+
+/*
+ * check-name: setne0-zext
+ * check-command: test-linearize -m64 -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-excludes: zext\\.
+ */
diff --git a/validation/optim/trunc-seteq0.c b/validation/optim/trunc-seteq0.c
new file mode 100644
index 00000000..5994b17c
--- /dev/null
+++ b/validation/optim/trunc-seteq0.c
@@ -0,0 +1,18 @@
+struct S {
+ int :1;
+ signed int s:2;
+ unsigned int u:3;
+};
+
+int os(int i, struct S *b) { return i || b->s; }
+int ou(int i, struct S *b) { return i || b->u; }
+
+/*
+ * check-name: trunc-seteq0
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-excludes: trunc\\.
+ * check-output-excludes: sext\\.
+ * check-output-excludes: zext\\.
+ */
diff --git a/validation/optim/trunc-setne0.c b/validation/optim/trunc-setne0.c
new file mode 100644
index 00000000..878c05fa
--- /dev/null
+++ b/validation/optim/trunc-setne0.c
@@ -0,0 +1,20 @@
+struct s {
+ unsigned int u:1;
+};
+
+unsigned int foo(struct s x)
+{
+ if (x.u)
+ return 1;
+ else
+ return 0;
+}
+
+/*
+ * check-name: trunc-setne0
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-contains: and\\.
+ * check-output-excludes: trunc\\.
+ */