This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Small tweak to RTL expansion of some array accesses on RISC targets


I noticed that, when a variable-sized object declared on the stack turns out 
to be of fixed size, the optimizer can replace the call to __builtin_alloca by 
the declaration of fixed-size local array.  Now, even if the alignment of the 
object is explicitly preserved, the alignment of its type is not since the 
type of the local array is always unsigned char.

On RISC targets (STRICT_ALIGNMENT / SLOW_UNALIGNED_ACCESS to be precise), this 
causes any read larger than unsigned char to go through the bitfield expansion 
circuitry, because expand_expr_real_1 has:

	    /* If the field isn't aligned enough to fetch as a memref,
 	       fetch it as a bit field.  */
 	    || (mode1 != BLKmode
		&& (((TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
		      || (bitpos % GET_MODE_ALIGNMENT (mode) != 0)
		      || (MEM_P (op0)
			  && (MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
			      || (bitpos % GET_MODE_ALIGNMENT (mode1) != 0))))
		     && modifier != EXPAND_MEMORY
		     && ((modifier == EXPAND_CONST_ADDRESS
			  || modifier == EXPAND_INITIALIZER)
			 ? STRICT_ALIGNMENT
			 : SLOW_UNALIGNED_ACCESS (mode1, MEM_ALIGN (op0))))

In other words, even if the alignment of the MEM is sufficient (and it is), 
the test on TYPE_ALIGN (TREE_TYPE (tem)) is true since TREE_TYPE (tem) is 
unsigned char.

I think that the test on TYPE_ALIGN (TREE_TYPE (tem)) is superfluous when op0 
is a MEM because the second part of the test is more precise and sufficient, 
so the attached patchlet uses a conditional expression to implement that.

Bootstrapped/regtested on SPARC/Solaris, SPARC64/Linux, PowerPC64/Linux and 
Aarch64/Linux, applied on the mainline as obvious.


2017-06-29  Eric Botcazou  <ebotcazou@adacore.com>

	* expr.c (expand_expr) <normal_inner_ref>: When testing for unaligned
	objects, take into account only the alignment of 'op0' and 'mode1' if
	'op0' is a MEM.

-- 
Eric Botcazou
Index: expr.c
===================================================================
--- expr.c	(revision 249619)
+++ expr.c	(working copy)
@@ -10631,11 +10631,11 @@ expand_expr_real_1 (tree exp, rtx target
 	    /* If the field isn't aligned enough to fetch as a memref,
 	       fetch it as a bit field.  */
 	    || (mode1 != BLKmode
-		&& (((TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
-		      || (bitpos % GET_MODE_ALIGNMENT (mode) != 0)
-		      || (MEM_P (op0)
-			  && (MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
-			      || (bitpos % GET_MODE_ALIGNMENT (mode1) != 0))))
+		&& (((MEM_P (op0)
+		      ? MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
+		        || (bitpos % GET_MODE_ALIGNMENT (mode1) != 0)
+		      : TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
+		        || (bitpos % GET_MODE_ALIGNMENT (mode) != 0))
 		     && modifier != EXPAND_MEMORY
 		     && ((modifier == EXPAND_CONST_ADDRESS
 			  || modifier == EXPAND_INITIALIZER)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]