@@ -12899,23 +12899,21 @@ maybe_optimize_sub_cmp_0 (enum tree_code code, tree *arg0, tree *arg1)
12899
12899
}
12900
12900
12901
12901
12902
- /* If CODE with arguments INNER & (1<<BITNUM) and 0 represents a single bit
12903
- equality/inequality test, then return a simplified form of
12904
- the test using shifts and logical operations. Otherwise return
12905
- NULL. TYPE is the desired result type. */
12902
+ /* Expand CODE with arguments INNER & (1<<BITNUM) and 0 that represents
12903
+ a single bit equality/inequality test, returns where the result is located. */
12906
12904
12907
- static tree
12908
- fold_single_bit_test (location_t loc, enum tree_code code,
12909
- tree inner, int bitnum,
12910
- tree result_type)
12905
+ static rtx
12906
+ expand_single_bit_test (location_t loc, enum tree_code code,
12907
+ tree inner, int bitnum,
12908
+ tree result_type, rtx target,
12909
+ machine_mode mode)
12911
12910
{
12912
12911
gcc_assert (code == NE_EXPR || code == EQ_EXPR);
12913
12912
12914
12913
tree type = TREE_TYPE (inner);
12915
12914
scalar_int_mode operand_mode = SCALAR_INT_TYPE_MODE (type);
12916
12915
int ops_unsigned;
12917
12916
tree signed_type, unsigned_type, intermediate_type;
12918
- tree one;
12919
12917
gimple *inner_def;
12920
12918
12921
12919
/* First, see if we can fold the single bit test into a sign-bit
@@ -12924,10 +12922,11 @@ fold_single_bit_test (location_t loc, enum tree_code code,
12924
12922
&& type_has_mode_precision_p (type))
12925
12923
{
12926
12924
tree stype = signed_type_for (type);
12927
- return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
12928
- result_type,
12929
- fold_convert_loc (loc, stype, inner),
12930
- build_int_cst (stype, 0 ));
12925
+ tree tmp = fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
12926
+ result_type,
12927
+ fold_convert_loc (loc, stype, inner),
12928
+ build_int_cst (stype, 0 ));
12929
+ return expand_expr (tmp, target, VOIDmode, EXPAND_NORMAL);
12931
12930
}
12932
12931
12933
12932
/* Otherwise we have (A & C) != 0 where C is a single bit,
@@ -12957,21 +12956,21 @@ fold_single_bit_test (location_t loc, enum tree_code code,
12957
12956
intermediate_type = ops_unsigned ? unsigned_type : signed_type;
12958
12957
inner = fold_convert_loc (loc, intermediate_type, inner);
12959
12958
12960
- tree bftype = build_nonstandard_integer_type (1 , 1 );
12961
- int bitpos = bitnum;
12962
-
12963
- if (BYTES_BIG_ENDIAN)
12964
- bitpos = GET_MODE_BITSIZE (operand_mode) - 1 - bitpos;
12959
+ rtx inner0 = expand_expr (inner, target, VOIDmode, EXPAND_NORMAL);
12965
12960
12966
- inner = build3_loc (loc, BIT_FIELD_REF, bftype, inner,
12967
- bitsize_int (1 ), bitsize_int (bitpos));
12968
-
12969
- one = build_int_cst (bftype, 1 );
12961
+ inner0 = extract_bit_field (inner0, 1 , bitnum, 1 , target,
12962
+ operand_mode, mode, 0 , NULL );
12970
12963
12971
12964
if (code == EQ_EXPR)
12972
- inner = fold_build2_loc (loc, BIT_XOR_EXPR, bftype, inner, one);
12973
-
12974
- return fold_convert_loc (loc, result_type, inner);
12965
+ inner0 = expand_binop (GET_MODE (inner0), xor_optab, inner0, const1_rtx,
12966
+ NULL_RTX, 1 , OPTAB_LIB_WIDEN);
12967
+ if (GET_MODE (inner0) != mode)
12968
+ {
12969
+ rtx t = gen_reg_rtx (mode);
12970
+ convert_move (t, inner0, 0 );
12971
+ return t;
12972
+ }
12973
+ return inner0;
12975
12974
}
12976
12975
12977
12976
/* Generate code to calculate OPS, and exploded expression
@@ -13150,10 +13149,7 @@ do_store_flag (sepops ops, rtx target, machine_mode mode)
13150
13149
do this by shifting the bit being tested to the low-order bit and
13151
13150
masking the result with the constant 1. If the condition was EQ,
13152
13151
we xor it with 1. This does not require an scc insn and is faster
13153
- than an scc insn even if we have it.
13154
-
13155
- The code to make this transformation was moved into fold_single_bit_test,
13156
- so we just call into the folder and expand its result. */
13152
+ than an scc insn even if we have it. */
13157
13153
13158
13154
if ((code == NE || code == EQ)
13159
13155
&& integer_zerop (arg1)
@@ -13163,16 +13159,13 @@ do_store_flag (sepops ops, rtx target, machine_mode mode)
13163
13159
if (srcstmt
13164
13160
&& integer_pow2p (gimple_assign_rhs2 (srcstmt)))
13165
13161
{
13166
- tree temp;
13167
13162
enum tree_code tcode = code == NE ? NE_EXPR : EQ_EXPR;
13168
13163
int bitnum = tree_log2 (gimple_assign_rhs2 (srcstmt));
13169
13164
13170
13165
type = lang_hooks.types .type_for_mode (mode, unsignedp);
13171
- temp = fold_single_bit_test (loc, tcode,
13172
- gimple_assign_rhs1 (srcstmt),
13173
- bitnum, type);
13174
- if (temp)
13175
- return expand_expr (temp, target, VOIDmode, EXPAND_NORMAL);
13166
+ return expand_single_bit_test (loc, tcode,
13167
+ gimple_assign_rhs1 (srcstmt),
13168
+ bitnum, type, target, mode);
13176
13169
}
13177
13170
}
13178
13171
0 commit comments