[aarch64-port-dev ] RFR: suppress implicit null check when offsets too large for immediate
Andrew Haley
aph at redhat.com
Thu Mar 20 16:25:02 UTC 2014
Hi,
On 03/19/2014 05:41 PM, Edward Nevill wrote:
> The following patch suppresses the null pointer check if the offset
> is too large to fit in a single load/store.
>
> This is necessary because in this case MacroAssembler::form_address
> can insert extra instructions before the load/store and the null
> pointer check can end up pointing to the wrong instruction.
>
> For simplicity in this patch I suppress the implicit null pointer
> check with any offset >= 1024 (ie I just pass 0 as the shift value
> to offset_ok_for_immed). The actual shift value does not seem to be
> readily available and I do not believe it will make any significant
> difference.
>
> This is not a pretty solution and I think it needs to be revised in
> the future with a better structured approach to handle this. However
> for now this will solve the problem.
I found the root cause of this problem. The operand types used by the
memory access instructions in aarch64.ad are wrong.
For example,
-operand indIndexScaledOffsetI(iRegP reg, iRegL lreg, immIScale scale, immIAddSub off)
+operand indIndexScaledOffsetI(iRegP reg, iRegL lreg, immIScale scale, immIU12 off)
Here we see that an immIAddSub is being used. This is wrong: it
allows more ranges than a scaled offset instruction, which only
accepts an unsigned 12-bit scaled offset. I've been through
aarch64.ad and fixed all of them, I hope.
Andrew.
# HG changeset patch
# User aph
# Date 1395332256 14400
# Thu Mar 20 12:17:36 2014 -0400
# Node ID 16e2ffe3b357aa5e6f7f255fd19777fa6c21a9c5
# Parent dd34c2dac1b81d174648b8dbcc667f39f2819b82
Correct operand perdicates used by load and store operands.
diff -r dd34c2dac1b8 -r 16e2ffe3b357 src/cpu/aarch64/vm/aarch64.ad
--- a/src/cpu/aarch64/vm/aarch64.ad Thu Mar 20 10:13:24 2014 -0400
+++ b/src/cpu/aarch64/vm/aarch64.ad Thu Mar 20 12:17:36 2014 -0400
@@ -3547,16 +3547,34 @@
interface(CONST_INTER);
%}
-// Valid 9 bit unsigned offset
-operand immI9()
-%{
- predicate(((-(1 << 8)) <= n->get_int()) && (n->get_int() < (1 << 8)));
+operand immLU12()
+%{
+ predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12)));
+ match(ConL);
+
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
+// Offset for scaled or unscaled immediate loads and stores
+operand immIOffset()
+%{
+ predicate(Address::offset_ok_for_immed(n->get_int()));
match(ConI);
format %{ %}
interface(CONST_INTER);
%}
+operand immLoffset()
+%{
+ predicate(Address::offset_ok_for_immed(n->get_long()));
+ match(ConL);
+
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
// 32 bit integer valid for add sub immediate
operand immIAddSub()
%{
@@ -4115,7 +4133,7 @@
%}
%}
-operand indIndexScaledOffsetI(iRegP reg, iRegL lreg, immIScale scale, immIAddSub off)
+operand indIndexScaledOffsetI(iRegP reg, iRegL lreg, immIScale scale, immIU12 off)
%{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP (AddP reg (LShiftL lreg scale)) off);
@@ -4129,7 +4147,7 @@
%}
%}
-operand indIndexScaledOffsetL(iRegP reg, iRegL lreg, immIScale scale, immLAddSub off)
+operand indIndexScaledOffsetL(iRegP reg, iRegL lreg, immIScale scale, immLU12 off)
%{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP (AddP reg (LShiftL lreg scale)) off);
@@ -4143,7 +4161,7 @@
%}
%}
-operand indIndexScaledOffsetI2L(iRegP reg, iRegI ireg, immIScale scale, immLAddSub off)
+operand indIndexScaledOffsetI2L(iRegP reg, iRegI ireg, immIScale scale, immLU12 off)
%{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off);
@@ -4199,7 +4217,7 @@
%}
%}
-operand indOffI(iRegP reg, immIAddSub off)
+operand indOffI(iRegP reg, immIOffset off)
%{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP reg off);
@@ -4213,7 +4231,7 @@
%}
%}
-operand indOffL(iRegP reg, immLAddSub off)
+operand indOffL(iRegP reg, immLoffset off)
%{
constraint(ALLOC_IN_RC(ptr_reg));
match(AddP reg off);
@@ -4243,7 +4261,7 @@
%}
%}
-operand indIndexScaledOffsetIN(iRegN reg, iRegL lreg, immIScale scale, immIAddSub off)
+operand indIndexScaledOffsetIN(iRegN reg, iRegL lreg, immIScale scale, immIU12 off)
%{
predicate(Universe::narrow_oop_shift() == 0);
constraint(ALLOC_IN_RC(ptr_reg));
@@ -4258,7 +4276,7 @@
%}
%}
-operand indIndexScaledOffsetLN(iRegN reg, iRegL lreg, immIScale scale, immLAddSub off)
+operand indIndexScaledOffsetLN(iRegN reg, iRegL lreg, immIScale scale, immLU12 off)
%{
predicate(Universe::narrow_oop_shift() == 0);
constraint(ALLOC_IN_RC(ptr_reg));
@@ -4273,7 +4291,7 @@
%}
%}
-operand indIndexScaledOffsetI2LN(iRegN reg, iRegI ireg, immIScale scale, immLAddSub off)
+operand indIndexScaledOffsetI2LN(iRegN reg, iRegI ireg, immIScale scale, immLU12 off)
%{
predicate(Universe::narrow_oop_shift() == 0);
constraint(ALLOC_IN_RC(ptr_reg));
@@ -4333,7 +4351,7 @@
%}
%}
-operand indOffIN(iRegN reg, immIAddSub off)
+operand indOffIN(iRegN reg, immIOffset off)
%{
predicate(Universe::narrow_oop_shift() == 0);
constraint(ALLOC_IN_RC(ptr_reg));
@@ -4348,7 +4366,7 @@
%}
%}
-operand indOffLN(iRegN reg, immLAddSub off)
+operand indOffLN(iRegN reg, immLoffset off)
%{
predicate(Universe::narrow_oop_shift() == 0);
constraint(ALLOC_IN_RC(ptr_reg));
More information about the aarch64-port-dev
mailing list