aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.cc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-02-09 16:17:08 +0100
committerJakub Jelinek <jakub@redhat.com>2024-02-09 16:17:08 +0100
commitc9bdcb0c3433ce09f5bb713a51a14130858578a2 (patch)
treee6b7101b6155fecb095a9a4dc51eb2cdeec67fb3 /gcc/expr.cc
parent2bb4556220285e92e599635c61029f25e9ca5e28 (diff)
downloadgcc-c9bdcb0c3433ce09f5bb713a51a14130858578a2.zip
gcc-c9bdcb0c3433ce09f5bb713a51a14130858578a2.tar.gz
gcc-c9bdcb0c3433ce09f5bb713a51a14130858578a2.tar.bz2
lower-bitint: Fix handling of VIEW_CONVERT_EXPRs to minimally supported huge INTEGER_TYPEs [PR113783]
On the following testcases memcpy lowering folds the calls to reading and writing of MEM_REFs with huge INTEGER_TYPEs - uint256_t with OImode or uint512_t with XImode. Further optimization turn the load from MEM_REF from the large/huge _BitInt var into VIEW_CONVERT_EXPR from it to the uint256_t/uint512_t. The backend doesn't really support those except for "movoi"/"movxi" insns, so it isn't possible to handle it like casts to supportable INTEGER_TYPEs where we can construct those from individual limbs - there are no OImode/XImode shifts and the like we can use. So, the following patch makes sure for such VCEs that the SSA_NAME operand of the VCE lives in memory and then turns it into a VIEW_CONVERT_EXPR so that we actually load the OImode/XImode integer from memory (i.e. a mov). We need to make sure those aren't merged with other operations in the gimple_lower_bitint hunks. For SSA_NAMEs which have underlying VAR_DECLs that is all we need, those VAR_DECL have ARRAY_TYPEs. For SSA_NAMEs which have underlying PARM_DECLs or RESULT_DECLs those have BITINT_TYPE and I had to tweak expand_expr_real_1 for that so that it doesn't try convert_modes on those when one of the modes is BLKmode - we want to fall through into the adjust_address on the MEM. 2024-02-09 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/113783 * gimple-lower-bitint.cc (bitint_large_huge::lower_stmt): Look through VIEW_CONVERT_EXPR for final cast checks. Handle VIEW_CONVERT_EXPRs from large/huge _BitInt to > MAX_FIXED_MODE_SIZE INTEGER_TYPEs. (gimple_lower_bitint): Don't merge mergeable operations or other casts with VIEW_CONVERT_EXPRs to > MAX_FIXED_MODE_SIZE INTEGER_TYPEs. * expr.cc (expand_expr_real_1): Don't use convert_modes if either mode is BLKmode. * gcc.dg/bitint-88.c: New test.
Diffstat (limited to 'gcc/expr.cc')
-rw-r--r--gcc/expr.cc5
1 files changed, 4 insertions, 1 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc
index fc5e998..444f04e 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -12445,7 +12445,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
}
}
/* If both types are integral, convert from one mode to the other. */
- else if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (TREE_TYPE (treeop0)))
+ else if (INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))
+ && mode != BLKmode
+ && GET_MODE (op0) != BLKmode)
op0 = convert_modes (mode, GET_MODE (op0), op0,
TYPE_UNSIGNED (TREE_TYPE (treeop0)));
/* If the output type is a bit-field type, do an extraction. */