[aarch64-port-dev ] RFR: aarch64: 8133842: C2 generates illegal instructions with int shifts >=32

Edward Nevill edward.nevill at gmail.com
Thu Aug 20 13:10:20 UTC 2015


On Thu, 2015-08-20 at 11:56 +0100, Andrew Haley wrote:
> Looks good for C2.  OK if you already checked C1!

Yes. For my test case

  res += i | (j >> 53);

C1 generates

  0x000003ff90eb0d68: lsr       w3, w1, #21
  0x000003ff90eb0d6c: orr       w3, w0, w3
  0x000003ff90eb0d70: add       w3, w3, w2

IE. It doesn't attempt to merge the shift and the or, and it masks the shift with 0x1f getting 21 instead of 53.

Below is the code in C1 that does it (from c1_LIRGenerator_aarch64.cpp). You can see it ands ints with 0x1f and longs with 0x3f.

All the best,
Ed.

--- cut here ---
  if (right.is_constant()) {
    right.dont_load_item();

    switch (x->op()) {
    case Bytecodes::_ishl: {
      int c = right.get_jint_constant() & 0x1f;
      __ shift_left(left.result(), c, x->operand());
      break;
    }
    case Bytecodes::_ishr: {
      int c = right.get_jint_constant() & 0x1f;
      __ shift_right(left.result(), c, x->operand());
      break;
    }
    case Bytecodes::_iushr: {
      int c = right.get_jint_constant() & 0x1f;
      __ unsigned_shift_right(left.result(), c, x->operand());
      break;
    }
    case Bytecodes::_lshl: {
      int c = right.get_jint_constant() & 0x3f;
      __ shift_left(left.result(), c, x->operand());
      break;
    }
    case Bytecodes::_lshr: {
      int c = right.get_jint_constant() & 0x3f;
      __ shift_right(left.result(), c, x->operand());
      break;
    }
    case Bytecodes::_lushr: {
      int c = right.get_jint_constant() & 0x3f;
      __ unsigned_shift_right(left.result(), c, x->operand());
      break;
    }
    default:
      ShouldNotReachHere();
    }
  } else {
--- cut here ---




More information about the aarch64-port-dev mailing list