Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
c2202b70
Commit
c2202b70
authored
Sep 02, 2015
by
yb9976
Browse files
Prevent optimization if compare relation is trivial.
This fixes opt/fehler302.c.
parent
3c5129c4
Changes
1
Hide whitespace changes
Inline
Side-by-side
ir/ir/iropt.c
View file @
c2202b70
...
...
@@ -5398,64 +5398,65 @@ cmp_x_eq_0:
/* for integer modes, we have more */
if
(
mode_is_int
(
mode
)
&&
!
is_Const
(
left
))
{
if
((
relation
==
ir_relation_less
||
relation
==
ir_relation_greater_equal
)
&&
tarval_cmp
(
tv
,
get_mode_null
(
mode
))
==
ir_relation_greater
)
{
bitinfo
const
*
const
bl
=
get_bitinfo
(
left
);
if
(
bl
&&
!
is_relation
(
ir_relation_false
,
relation
,
possible
)
&&
!
is_relation
(
ir_relation_true
,
relation
,
possible
))
{
ir_tarval
*
const
uneq
=
tarval_or
(
tarval_andnot
(
tv
,
bl
->
z
),
tarval_andnot
(
bl
->
o
,
tv
));
int
const
hi
=
get_tarval_highest_bit
(
uneq
);
if
(
hi
>=
0
)
{
/* Example: 0b????0101 < 0b11001000 -> 0b????0101 <= 0b11000101
* It is possible that o <= tv <= z and it is known that left and
* tv differ in at least one bit. Reduce the constant by the
* value of the highest differing bit and set all bits below to
* the maximum possible value of the left hand side, i.e. z.
* This converges in O(n) in comparison to l < c -> l <= c - 1,
* which converges in O(2**n). */
ir_tarval
*
const
one
=
get_mode_one
(
mode
);
ir_tarval
*
const
hibit
=
tarval_shl_unsigned
(
one
,
hi
);
ir_tarval
*
const
mask
=
tarval_sub
(
hibit
,
one
,
NULL
);
tv
=
tarval_or
(
tarval_andnot
(
tarval_sub
(
tv
,
hibit
,
NULL
),
mask
),
tarval_and
(
bl
->
z
,
mask
));
goto
reduced_tv
;
if
(
!
is_relation
(
ir_relation_false
,
relation
,
possible
)
&&
!
is_relation
(
ir_relation_true
,
relation
,
possible
))
{
if
((
relation
==
ir_relation_less
||
relation
==
ir_relation_greater_equal
)
&&
tarval_cmp
(
tv
,
get_mode_null
(
mode
))
==
ir_relation_greater
)
{
bitinfo
const
*
const
bl
=
get_bitinfo
(
left
);
if
(
bl
)
{
ir_tarval
*
const
uneq
=
tarval_or
(
tarval_andnot
(
tv
,
bl
->
z
),
tarval_andnot
(
bl
->
o
,
tv
));
int
const
hi
=
get_tarval_highest_bit
(
uneq
);
if
(
hi
>=
0
)
{
/* Example: 0b????0101 < 0b11001000 -> 0b????0101 <= 0b11000101
* It is possible that o <= tv <= z and it is known that left and
* tv differ in at least one bit. Reduce the constant by the
* value of the highest differing bit and set all bits below to
* the maximum possible value of the left hand side, i.e. z.
* This converges in O(n) in comparison to l < c -> l <= c - 1,
* which converges in O(2**n). */
ir_tarval
*
const
one
=
get_mode_one
(
mode
);
ir_tarval
*
const
hibit
=
tarval_shl_unsigned
(
one
,
hi
);
ir_tarval
*
const
mask
=
tarval_sub
(
hibit
,
one
,
NULL
);
tv
=
tarval_or
(
tarval_andnot
(
tarval_sub
(
tv
,
hibit
,
NULL
),
mask
),
tarval_and
(
bl
->
z
,
mask
));
goto
reduced_tv
;
}
}
}
/* c > 0 : a < c ==> a <= (c - 1) a >= c ==> a > (c - 1) */
tv
=
tarval_sub
(
tv
,
get_mode_one
(
mode
),
NULL
);
goto
reduced_tv
;
}
else
if
((
relation
==
ir_relation_greater
||
relation
==
ir_relation_less_equal
)
&&
tarval_cmp
(
tv
,
get_mode_null
(
mode
))
==
ir_relation_less
)
{
bitinfo
const
*
const
bl
=
get_bitinfo
(
left
);
if
(
bl
&&
!
is_relation
(
ir_relation_false
,
relation
,
possible
)
&&
!
is_relation
(
ir_relation_true
,
relation
,
possible
))
{
ir_tarval
*
const
uneq
=
tarval_or
(
tarval_andnot
(
tv
,
bl
->
z
),
tarval_andnot
(
bl
->
o
,
tv
)
);
int
const
hi
=
get_tarval_highest_bit
(
uneq
);
if
(
hi
>=
0
)
{
/* Example: 0b????0101 > 0b11001000 -> 0b????0101 >= 0b11010101
*
It is possible that o <= tv <= z and it is known that left and
*
t
v differ
in
at least one bit. Increase the constant by the
*
value of the highest differing bi
t and s
et all bits below to
*
the maximum possible value of the left hand side, i.e. z.
*
T
hi
s
converges in O(
n) in comparison to l > c -> l >= c + 1,
* which converges in O(2**n). */
ir_tarval
*
const
one
=
get_mode_one
(
mode
);
ir_tarval
*
const
hibit
=
tarval_s
hl_unsigned
(
one
,
hi
);
ir_tarval
*
const
mask
=
tarval_
sub
(
hibit
,
one
,
NULL
);
tv
=
tarval_or
(
tarval_andnot
(
tarval_add
(
tv
,
hibit
),
mask
),
tarval_and
(
bl
->
o
,
mask
))
;
goto
reduced_tv
;
/* c > 0 : a < c ==> a <= (c - 1) a >= c ==> a > (c - 1) */
tv
=
tarval_sub
(
tv
,
get_mode_one
(
mode
),
NULL
);
goto
reduced_tv
;
}
else
if
((
relation
==
ir_relation_greater
||
relation
==
ir_relation_less_equal
)
&&
tarval_cmp
(
tv
,
get_mode_null
(
mode
))
==
ir_relation_less
)
{
bitinfo
const
*
const
bl
=
get_bitinfo
(
left
);
if
(
bl
)
{
ir_tarval
*
const
uneq
=
tarval_or
(
tarval_andnot
(
tv
,
bl
->
z
),
tarval_andnot
(
bl
->
o
,
tv
));
int
const
hi
=
get_tarval_highest_bit
(
uneq
);
if
(
hi
>=
0
)
{
/* Example: 0b????0101 > 0b11001000 -> 0b????0101 >= 0b11010101
* It is possible that o <= tv <= z and it is known that left and
*
tv differ in at least one bit. Increase the constant by the
* v
alue of the highest
differin
g bit and set all bits below to
*
the maximum possible value of the lef
t
h
and s
ide, i.e. z.
*
This converges in O(n) in comparison to l > c -> l >= c + 1,
*
w
hi
ch
converges in O(
2**n). */
ir_tarval
*
const
one
=
get_mode_one
(
mode
);
ir_tarval
*
const
hibit
=
tarval_shl_unsigned
(
one
,
hi
);
ir_tarval
*
const
mask
=
tarval_s
ub
(
hibit
,
one
,
NULL
);
tv
=
tarval_or
(
tarval_andnot
(
tarval_add
(
tv
,
hibit
),
mask
),
tarval_
and
(
bl
->
o
,
mask
)
);
goto
reduced_tv
;
}
}
}
/* c < 0 : a > c ==> a >= (c + 1) a <= c ==> a < (c + 1) */
tv
=
tarval_add
(
tv
,
get_mode_one
(
mode
));
/* c < 0 : a > c ==> a >= (c + 1) a <= c ==> a < (c + 1) */
tv
=
tarval_add
(
tv
,
get_mode_one
(
mode
));
reduced_tv:
assert
(
tarval_is_constant
(
tv
));
relation
^=
ir_relation_equal
;
rel_eq
=
get_complementary_relations
(
ir_relation_equal
,
relation
,
possible
);
changedc
=
true
;
DBG_OPT_ALGSIM0
(
n
,
n
,
FS_OPT_CMP_CNST_MAGN
);
assert
(
tarval_is_constant
(
tv
));
relation
^=
ir_relation_equal
;
rel_eq
=
get_complementary_relations
(
ir_relation_equal
,
relation
,
possible
);
changedc
=
true
;
DBG_OPT_ALGSIM0
(
n
,
n
,
FS_OPT_CMP_CNST_MAGN
);
}
}
/* the following reassociations work only for == and != */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment