changeset 16346:bbf051d717f5

Propagate reference information through arithmetics.
author Roland Schatz <roland.schatz@oracle.com>
date Tue, 01 Jul 2014 16:06:17 +0200
parents d0c5f9bc7d98
children c6a1215d025b
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LIRKind.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java
diffstat 9 files changed, 197 insertions(+), 168 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LIRKind.java	Tue Jul 01 15:37:38 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LIRKind.java	Tue Jul 01 16:06:17 2014 +0200
@@ -71,12 +71,37 @@
     }
 
     /**
+     * Derive a new type from inputs. The result will have the {@link PlatformKind} of one of the
+     * inputs. If all inputs are values, the result is a value. Otherwise, the result is a derived
+     * reference.
+     *
+     * This method should be used to construct the result {@link LIRKind} of any operation that
+     * modifies values (e.g. arithmetics).
+     */
+    public static LIRKind derive(Value... inputs) {
+        assert inputs.length > 0;
+        for (Value input : inputs) {
+            LIRKind kind = input.getLIRKind();
+            if (kind.isDerivedReference()) {
+                return kind;
+            } else if (!kind.isValue()) {
+                return kind.makeDerivedReference();
+            }
+        }
+
+        // all inputs are values, just return one of them
+        return inputs[0].getLIRKind();
+    }
+
+    /**
      * Create a new {@link LIRKind} with the same reference information and a new
      * {@linkplain #getPlatformKind platform kind}. If the new kind is a longer vector than this,
      * the new elements are marked as untracked values.
      */
     public LIRKind changeType(PlatformKind newPlatformKind) {
-        if (isDerivedReference()) {
+        if (newPlatformKind == platformKind) {
+            return this;
+        } else if (isDerivedReference()) {
             return derivedReference(newPlatformKind);
         } else if (referenceMask == 0) {
             // value type
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Jul 01 15:37:38 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Jul 01 16:06:17 2014 +0200
@@ -77,10 +77,6 @@
  */
 public abstract class AMD64LIRGenerator extends LIRGenerator {
 
-    private static final RegisterValue RAX_I = AMD64.rax.asValue(LIRKind.value(Kind.Int));
-    private static final RegisterValue RAX_L = AMD64.rax.asValue(LIRKind.value(Kind.Long));
-    private static final RegisterValue RDX_I = AMD64.rdx.asValue(LIRKind.value(Kind.Int));
-    private static final RegisterValue RDX_L = AMD64.rdx.asValue(LIRKind.value(Kind.Long));
     private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(Kind.Int));
 
     private class AMD64SpillMoveFactory implements LIR.SpillMoveFactory {
@@ -433,7 +429,7 @@
     @Override
     public Variable emitNegate(Value inputVal) {
         AllocatableValue input = asAllocatable(inputVal);
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind()) {
             case Int:
                 append(new Unary1Op(INEG, result, input));
@@ -456,7 +452,7 @@
     @Override
     public Variable emitNot(Value inputVal) {
         AllocatableValue input = asAllocatable(inputVal);
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind()) {
             case Int:
                 append(new Unary1Op(INOT, result, input));
@@ -493,7 +489,7 @@
             case IXOR:
             case LXOR:
                 if (NumUtil.isInt(b.asLong())) {
-                    Variable result = newVariable(a.getLIRKind());
+                    Variable result = newVariable(LIRKind.derive(a, b));
                     append(new BinaryRegConst(op, result, a, b));
                     return result;
                 }
@@ -502,7 +498,7 @@
             case IMUL:
             case LMUL:
                 if (NumUtil.isInt(b.asLong())) {
-                    Variable result = newVariable(a.getLIRKind());
+                    Variable result = newVariable(LIRKind.derive(a, b));
                     append(new BinaryRegStackConst(op, result, a, b));
                     return result;
                 }
@@ -513,7 +509,7 @@
     }
 
     private Variable emitBinaryVar(AMD64Arithmetic op, boolean commutative, AllocatableValue a, AllocatableValue b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         if (commutative) {
             append(new BinaryCommutative(op, result, a, b));
         } else {
@@ -571,7 +567,7 @@
     }
 
     private Value emitMulHigh(AMD64Arithmetic opcode, Value a, Value b) {
-        MulHighOp mulHigh = new MulHighOp(opcode, asAllocatable(b));
+        MulHighOp mulHigh = new MulHighOp(opcode, LIRKind.derive(a, b), asAllocatable(b));
         emitMove(mulHigh.x, a);
         append(mulHigh);
         return emitMove(mulHigh.highResult);
@@ -602,7 +598,7 @@
     }
 
     public Value emitBinaryMemory(AMD64Arithmetic op, Kind kind, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a));
         append(new BinaryMemory(op, kind, result, a, location, state));
         return result;
     }
@@ -621,41 +617,45 @@
         return result;
     }
 
-    private void emitDivRem(AMD64Arithmetic op, Value a, Value b, LIRFrameState state) {
+    private DivRemOp emitDivRem(AMD64Arithmetic op, Value a, Value b, LIRFrameState state) {
         AllocatableValue rax = AMD64.rax.asValue(a.getLIRKind());
         emitMove(rax, a);
-        append(new DivRemOp(op, rax, asAllocatable(b), state));
+        DivRemOp ret = new DivRemOp(op, rax, asAllocatable(b), state);
+        append(ret);
+        return ret;
     }
 
     public Value[] emitIntegerDivRem(Value a, Value b, LIRFrameState state) {
+        DivRemOp op;
         switch (a.getKind().getStackKind()) {
             case Int:
-                emitDivRem(IDIVREM, a, b, state);
-                return new Value[]{emitMove(RAX_I), emitMove(RDX_I)};
+                op = emitDivRem(IDIVREM, a, b, state);
+                break;
             case Long:
-                emitDivRem(LDIVREM, a, b, state);
-                return new Value[]{emitMove(RAX_L), emitMove(RDX_L)};
+                op = emitDivRem(LDIVREM, a, b, state);
+                break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
+        return new Value[]{emitMove(op.divResult), emitMove(op.remResult)};
     }
 
     @Override
     public Value emitDiv(Value a, Value b, LIRFrameState state) {
         switch (a.getKind().getStackKind()) {
             case Int:
-                emitDivRem(IDIV, a, b, state);
-                return emitMove(RAX_I);
+                DivRemOp op = emitDivRem(IDIV, a, b, state);
+                return emitMove(op.divResult);
             case Long:
-                emitDivRem(LDIV, a, b, state);
-                return emitMove(RAX_L);
+                DivRemOp lop = emitDivRem(LDIV, a, b, state);
+                return emitMove(lop.divResult);
             case Float: {
-                Variable result = newVariable(a.getLIRKind());
+                Variable result = newVariable(LIRKind.derive(a, b));
                 append(new BinaryRegStack(FDIV, result, asAllocatable(a), asAllocatable(b)));
                 return result;
             }
             case Double: {
-                Variable result = newVariable(a.getLIRKind());
+                Variable result = newVariable(LIRKind.derive(a, b));
                 append(new BinaryRegStack(DDIV, result, asAllocatable(a), asAllocatable(b)));
                 return result;
             }
@@ -668,18 +668,18 @@
     public Value emitRem(Value a, Value b, LIRFrameState state) {
         switch (a.getKind().getStackKind()) {
             case Int:
-                emitDivRem(IREM, a, b, state);
-                return emitMove(RDX_I);
+                DivRemOp op = emitDivRem(IREM, a, b, state);
+                return emitMove(op.remResult);
             case Long:
-                emitDivRem(LREM, a, b, state);
-                return emitMove(RDX_L);
+                DivRemOp lop = emitDivRem(LREM, a, b, state);
+                return emitMove(lop.remResult);
             case Float: {
-                Variable result = newVariable(a.getLIRKind());
+                Variable result = newVariable(LIRKind.derive(a, b));
                 append(new FPDivRemOp(FREM, result, load(a), load(b)));
                 return result;
             }
             case Double: {
-                Variable result = newVariable(a.getLIRKind());
+                Variable result = newVariable(LIRKind.derive(a, b));
                 append(new FPDivRemOp(DREM, result, load(a), load(b)));
                 return result;
             }
@@ -690,30 +690,34 @@
 
     @Override
     public Variable emitUDiv(Value a, Value b, LIRFrameState state) {
+        DivRemOp op;
         switch (a.getKind().getStackKind()) {
             case Int:
-                emitDivRem(IUDIV, a, b, state);
-                return emitMove(RAX_I);
+                op = emitDivRem(IUDIV, a, b, state);
+                break;
             case Long:
-                emitDivRem(LUDIV, a, b, state);
-                return emitMove(RAX_L);
+                op = emitDivRem(LUDIV, a, b, state);
+                break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
+        return emitMove(op.divResult);
     }
 
     @Override
     public Variable emitURem(Value a, Value b, LIRFrameState state) {
+        DivRemOp op;
         switch (a.getKind().getStackKind()) {
             case Int:
-                emitDivRem(IUREM, a, b, state);
-                return emitMove(RDX_I);
+                op = emitDivRem(IUREM, a, b, state);
+                break;
             case Long:
-                emitDivRem(LUREM, a, b, state);
-                return emitMove(RDX_L);
+                op = emitDivRem(LUREM, a, b, state);
+                break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
+        return emitMove(op.remResult);
     }
 
     @Override
@@ -753,7 +757,7 @@
     }
 
     private Variable emitShift(AMD64Arithmetic op, Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b).changeType(a.getPlatformKind()));
         AllocatableValue input = asAllocatable(a);
         if (isConstant(b)) {
             append(new BinaryRegConst(op, result, input, asConstant(b)));
@@ -880,25 +884,25 @@
         AllocatableValue input = asAllocatable(inputVal);
         switch (op) {
             case D2F:
-                return emitConvert2Op(LIRKind.value(Kind.Float), D2F, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), D2F, input);
             case D2I:
-                return emitConvert2Op(LIRKind.value(Kind.Int), D2I, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Int), D2I, input);
             case D2L:
-                return emitConvert2Op(LIRKind.value(Kind.Long), D2L, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Long), D2L, input);
             case F2D:
-                return emitConvert2Op(LIRKind.value(Kind.Double), F2D, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), F2D, input);
             case F2I:
-                return emitConvert2Op(LIRKind.value(Kind.Int), F2I, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Int), F2I, input);
             case F2L:
-                return emitConvert2Op(LIRKind.value(Kind.Long), F2L, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Long), F2L, input);
             case I2D:
-                return emitConvert2Op(LIRKind.value(Kind.Double), I2D, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), I2D, input);
             case I2F:
-                return emitConvert2Op(LIRKind.value(Kind.Float), I2F, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), I2F, input);
             case L2D:
-                return emitConvert2Op(LIRKind.value(Kind.Double), L2D, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), L2D, input);
             case L2F:
-                return emitConvert2Op(LIRKind.value(Kind.Float), L2F, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), L2F, input);
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
@@ -908,7 +912,7 @@
     public Value emitNarrow(Value inputVal, int bits) {
         if (inputVal.getKind() == Kind.Long && bits <= 32) {
             // TODO make it possible to reinterpret Long as Int in LIR without move
-            return emitConvert2RegOp(LIRKind.value(Kind.Int), L2I, asAllocatable(inputVal));
+            return emitConvert2RegOp(LIRKind.derive(inputVal).changeType(Kind.Int), L2I, asAllocatable(inputVal));
         } else {
             return inputVal;
         }
@@ -923,11 +927,11 @@
             // sign extend to 64 bits
             switch (fromBits) {
                 case 8:
-                    return emitConvert2Op(LIRKind.value(Kind.Long), B2L, asAllocatable(inputVal));
+                    return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Long), B2L, asAllocatable(inputVal));
                 case 16:
-                    return emitConvert2Op(LIRKind.value(Kind.Long), S2L, asAllocatable(inputVal));
+                    return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Long), S2L, asAllocatable(inputVal));
                 case 32:
-                    return emitConvert2Op(LIRKind.value(Kind.Long), I2L, asAllocatable(inputVal));
+                    return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Long), I2L, asAllocatable(inputVal));
                 default:
                     throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
             }
@@ -935,9 +939,9 @@
             // sign extend to 32 bits (smaller values are internally represented as 32 bit values)
             switch (fromBits) {
                 case 8:
-                    return emitConvert2Op(LIRKind.value(Kind.Int), B2I, asAllocatable(inputVal));
+                    return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Int), B2I, asAllocatable(inputVal));
                 case 16:
-                    return emitConvert2Op(LIRKind.value(Kind.Int), S2I, asAllocatable(inputVal));
+                    return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Int), S2I, asAllocatable(inputVal));
                 case 32:
                     return inputVal;
                 default:
@@ -953,17 +957,17 @@
             return inputVal;
         } else if (fromBits > 32) {
             assert inputVal.getKind() == Kind.Long;
-            Variable result = newVariable(LIRKind.value(Kind.Long));
+            Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
             long mask = IntegerStamp.defaultMask(fromBits);
             append(new BinaryRegConst(AMD64Arithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask)));
             return result;
         } else {
             assert inputVal.getKind().getStackKind() == Kind.Int;
-            Variable result = newVariable(LIRKind.value(Kind.Int));
+            Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int));
             int mask = (int) IntegerStamp.defaultMask(fromBits);
             append(new BinaryRegConst(AMD64Arithmetic.IAND, result, asAllocatable(inputVal), Constant.forInt(mask)));
             if (toBits > 32) {
-                Variable longResult = newVariable(LIRKind.value(Kind.Long));
+                Variable longResult = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
                 emitMove(longResult, result);
                 return longResult;
             } else {
@@ -994,7 +998,7 @@
 
     @Override
     public Value emitBitCount(Value value) {
-        Variable result = newVariable(LIRKind.value(Kind.Int));
+        Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int));
         if (value.getKind().getStackKind() == Kind.Int) {
             append(new AMD64BitManipulationOp(IPOPCNT, result, asAllocatable(value)));
         } else {
@@ -1005,14 +1009,14 @@
 
     @Override
     public Value emitBitScanForward(Value value) {
-        Variable result = newVariable(LIRKind.value(Kind.Int));
+        Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int));
         append(new AMD64BitManipulationOp(BSF, result, asAllocatable(value)));
         return result;
     }
 
     @Override
     public Value emitBitScanReverse(Value value) {
-        Variable result = newVariable(LIRKind.value(Kind.Int));
+        Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int));
         if (value.getKind().getStackKind() == Kind.Int) {
             append(new AMD64BitManipulationOp(IBSR, result, asAllocatable(value)));
         } else {
@@ -1023,49 +1027,49 @@
 
     @Override
     public Value emitMathAbs(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new BinaryRegConst(DAND, result, asAllocatable(input), Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL))));
         return result;
     }
 
     @Override
     public Value emitMathSqrt(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new Unary2Op(SQRT, result, asAllocatable(input)));
         return result;
     }
 
     @Override
     public Value emitMathLog(Value input, boolean base10) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new AMD64MathIntrinsicOp(base10 ? LOG10 : LOG, result, asAllocatable(input)));
         return result;
     }
 
     @Override
     public Value emitMathCos(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new AMD64MathIntrinsicOp(COS, result, asAllocatable(input)));
         return result;
     }
 
     @Override
     public Value emitMathSin(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new AMD64MathIntrinsicOp(SIN, result, asAllocatable(input)));
         return result;
     }
 
     @Override
     public Value emitMathTan(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new AMD64MathIntrinsicOp(TAN, result, asAllocatable(input)));
         return result;
     }
 
     @Override
     public Value emitByteSwap(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new AMD64ByteSwapOp(result, input));
         return result;
     }
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Tue Jul 01 15:37:38 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Tue Jul 01 16:06:17 2014 +0200
@@ -249,7 +249,7 @@
      */
     @Override
     public Variable emitNegate(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind()) {
             case Int:
                 // Note: The Int case also handles the negation of shorts, bytes, and chars because
@@ -280,7 +280,7 @@
      */
     @Override
     public Variable emitNot(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind()) {
             case Int:
                 // Note: The Int case also covers other primitive integral types smaller than an int
@@ -298,7 +298,7 @@
     }
 
     public Variable emitTestAddressAdd(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(IADD, result, a, loadNonConst(b)));
@@ -323,7 +323,7 @@
 
     @Override
     public Variable emitAdd(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(IADD, result, a, loadNonConst(b)));
@@ -348,7 +348,7 @@
 
     @Override
     public Variable emitSub(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(ISUB, result, a, loadNonConst(b)));
@@ -370,7 +370,7 @@
 
     @Override
     public Variable emitMul(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(IMUL, result, a, loadNonConst(b)));
@@ -391,7 +391,7 @@
     }
 
     public Variable emitUMul(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(LUMUL, result, a, loadNonConst(b)));
@@ -417,7 +417,7 @@
 
     @Override
     public Value emitDiv(Value a, Value b, LIRFrameState state) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(IDIV, result, a, loadNonConst(b)));
@@ -440,7 +440,7 @@
 
     @Override
     public Value emitRem(Value a, Value b, LIRFrameState state) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(IREM, result, a, loadNonConst(b)));
@@ -472,7 +472,7 @@
 
     @Override
     public Variable emitAnd(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(IAND, result, a, loadNonConst(b)));
@@ -488,7 +488,7 @@
 
     @Override
     public Variable emitOr(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(IOR, result, a, loadNonConst(b)));
@@ -504,7 +504,7 @@
 
     @Override
     public Variable emitXor(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(IXOR, result, a, loadNonConst(b)));
@@ -527,7 +527,7 @@
      */
     @Override
     public Variable emitShl(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b).changeType(a.getPlatformKind()));
         switch (a.getKind()) {
             case Int:
                 // Note: The Int case also covers the shifting of bytes, shorts and chars because
@@ -552,7 +552,7 @@
      */
     @Override
     public Variable emitShr(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b).changeType(a.getPlatformKind()));
         switch (a.getKind()) {
             case Int:
                 // Note: The Int case also covers the shifting of bytes, shorts and chars because
@@ -577,7 +577,7 @@
      */
     @Override
     public Variable emitUShr(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b).changeType(a.getPlatformKind()));
         switch (a.getKind()) {
             case Int:
                 append(new ShiftOp(IUSHR, result, a, b));
@@ -625,24 +625,24 @@
             case D2I:
             case F2I:
                 to = "s32";
-                result = newVariable(LIRKind.value(Kind.Int));
+                result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int));
                 break;
             case D2L:
             case F2L:
                 to = "s64";
-                result = newVariable(LIRKind.value(Kind.Long));
+                result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
                 break;
             case F2D:
             case I2D:
             case L2D:
                 to = "f64";
-                result = newVariable(LIRKind.value(Kind.Double));
+                result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Double));
                 break;
             case D2F:
             case I2F:
             case L2F:
                 to = "f32";
-                result = newVariable(LIRKind.value(Kind.Float));
+                result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Float));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -655,7 +655,7 @@
     @Override
     public Value emitNarrow(Value inputVal, int bits) {
         Variable input = load(inputVal);
-        Variable result = newVariable(LIRKind.value(bits > 32 ? Kind.Long : Kind.Int));
+        Variable result = newVariable(LIRKind.derive(inputVal).changeType(bits > 32 ? Kind.Long : Kind.Int));
         append(new ConvertOp(result, input, "s" + bits, input.getKind() == Kind.Long ? "s64" : "s32"));
         return result;
     }
@@ -663,7 +663,7 @@
     @Override
     public Value emitSignExtend(Value inputVal, int fromBits, int toBits) {
         Variable input = load(inputVal);
-        Variable result = newVariable(LIRKind.value(toBits > 32 ? Kind.Long : Kind.Int));
+        Variable result = newVariable(LIRKind.derive(inputVal).changeType(toBits > 32 ? Kind.Long : Kind.Int));
         append(new ConvertOp(result, input, "s" + toBits, "s" + fromBits));
         return result;
     }
@@ -671,7 +671,7 @@
     @Override
     public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) {
         Variable input = load(inputVal);
-        Variable result = newVariable(LIRKind.value(toBits > 32 ? Kind.Long : Kind.Int));
+        Variable result = newVariable(LIRKind.derive(inputVal).changeType(toBits > 32 ? Kind.Long : Kind.Int));
         append(new ConvertOp(result, input, "u" + toBits, "u" + fromBits));
         return result;
     }
@@ -696,7 +696,7 @@
 
     @Override
     public Value emitBitCount(Value value) {
-        Variable result = newVariable(LIRKind.value(Kind.Int));
+        Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int));
         if (value.getKind().getStackKind() == Kind.Int) {
             append(new HSAILBitManipulationOp(IPOPCNT, result, value));
         } else {
@@ -723,7 +723,7 @@
      */
     @Override
     public Value emitMathAbs(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new Op1Reg(ABS, result, input));
         return result;
     }
@@ -735,7 +735,7 @@
      * @return Value representing the result of the operation
      */
     public Value emitMathCeil(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new Op1Reg(CEIL, result, input));
         return result;
     }
@@ -747,7 +747,7 @@
      * @return Value representing the result of the operation
      */
     public Value emitMathFloor(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new Op1Reg(FLOOR, result, input));
         return result;
     }
@@ -759,7 +759,7 @@
      * @return Value representing the result of the operation
      */
     public Value emitMathRint(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new Op1Reg(RINT, result, input));
         return result;
     }
@@ -772,7 +772,7 @@
      */
     @Override
     public Value emitMathSqrt(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new Op1Reg(SQRT, result, input));
         return result;
     }
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Tue Jul 01 15:37:38 2014 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Tue Jul 01 16:06:17 2014 +0200
@@ -192,7 +192,7 @@
                 if (baseRegister.equals(Value.ILLEGAL)) {
                     baseRegister = asAllocatable(indexRegister);
                 } else {
-                    Variable longBaseRegister = newVariable(LIRKind.value(Kind.Long));
+                    Variable longBaseRegister = newVariable(LIRKind.derivedReference(Kind.Long));
                     emitMove(longBaseRegister, baseRegister);
                     baseRegister = emitAdd(longBaseRegister, indexRegister);
                 }
@@ -370,7 +370,7 @@
 
     @Override
     public Variable emitNegate(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind()) {
             case Int:
                 append(new Op1Stack(INEG, result, input));
@@ -389,7 +389,7 @@
 
     @Override
     public Variable emitNot(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind()) {
             case Int:
                 append(new Op1Stack(INOT, result, input));
@@ -405,7 +405,7 @@
 
     @Override
     public Variable emitAdd(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Stack(IADD, result, a, loadNonConst(b)));
@@ -427,7 +427,7 @@
 
     @Override
     public Variable emitSub(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Stack(ISUB, result, a, loadNonConst(b)));
@@ -449,7 +449,7 @@
 
     @Override
     public Variable emitMul(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(IMUL, result, a, loadNonConst(b)));
@@ -481,7 +481,7 @@
 
     @Override
     public Value emitDiv(Value a, Value b, LIRFrameState state) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(IDIV, result, a, loadNonConst(b)));
@@ -503,7 +503,7 @@
 
     @Override
     public Value emitRem(Value a, Value b, LIRFrameState state) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Reg(IREM, result, a, loadNonConst(b)));
@@ -529,7 +529,7 @@
 
     @Override
     public Variable emitAnd(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Stack(IAND, result, a, loadNonConst(b)));
@@ -545,7 +545,7 @@
 
     @Override
     public Variable emitOr(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Stack(IOR, result, a, loadNonConst(b)));
@@ -561,7 +561,7 @@
 
     @Override
     public Variable emitXor(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Stack(IXOR, result, a, loadNonConst(b)));
@@ -577,7 +577,7 @@
 
     @Override
     public Variable emitShl(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b).changeType(a.getPlatformKind()));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Stack(ISHL, result, a, loadNonConst(b)));
@@ -593,7 +593,7 @@
 
     @Override
     public Variable emitShr(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b).changeType(a.getPlatformKind()));
         switch (a.getKind()) {
             case Int:
                 append(new Op2Stack(ISHR, result, a, loadNonConst(b)));
@@ -609,7 +609,7 @@
 
     @Override
     public Variable emitUShr(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b).changeType(a.getPlatformKind()));
         switch (a.getKind()) {
             case Int:
                 append(new ShiftOp(IUSHR, result, a, b));
@@ -625,7 +625,7 @@
 
     public Variable emitConvertOp(Kind from, Kind to, Value inputVal) {
         Variable input = load(inputVal);
-        Variable result = newVariable(LIRKind.value(to));
+        Variable result = newVariable(LIRKind.derive(inputVal).changeType(to));
         append(new ConvertOp(result, input, to, from));
         return result;
     }
@@ -708,17 +708,17 @@
             return inputVal;
         } else if (fromBits > 32) {
             assert inputVal.getKind() == Kind.Long;
-            Variable result = newVariable(LIRKind.value(Kind.Long));
+            Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
             long mask = IntegerStamp.defaultMask(fromBits);
             append(new Op2Stack(LAND, result, inputVal, Constant.forLong(mask)));
             return result;
         } else {
             assert inputVal.getKind() == Kind.Int;
-            Variable result = newVariable(LIRKind.value(Kind.Int));
+            Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int));
             int mask = (int) IntegerStamp.defaultMask(fromBits);
             append(new Op2Stack(IAND, result, inputVal, Constant.forInt(mask)));
             if (toBits > 32) {
-                Variable longResult = newVariable(LIRKind.value(Kind.Long));
+                Variable longResult = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
                 emitMove(longResult, result);
                 return longResult;
             } else {
@@ -751,7 +751,7 @@
 
     @Override
     public Value emitBitCount(Value value) {
-        Variable result = newVariable(LIRKind.value(Kind.Int));
+        Variable result = newVariable(LIRKind.derive(value).changeType(Kind.Int));
         if (value.getKind().getStackKind() == Kind.Int) {
             append(new PTXBitManipulationOp(IPOPCNT, result, value));
         } else {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Jul 01 15:37:38 2014 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Jul 01 16:06:17 2014 +0200
@@ -366,7 +366,7 @@
 
     @Override
     public Value emitBitCount(Value operand) {
-        Variable result = newVariable(LIRKind.value(Kind.Int));
+        Variable result = newVariable(LIRKind.derive(operand).changeType(Kind.Int));
         if (operand.getKind().getStackKind() == Kind.Int) {
             append(new SPARCBitManipulationOp(IPOPCNT, result, asAllocatable(operand), this));
         } else {
@@ -377,14 +377,14 @@
 
     @Override
     public Value emitBitScanForward(Value operand) {
-        Variable result = newVariable(LIRKind.value(Kind.Int));
+        Variable result = newVariable(LIRKind.derive(operand).changeType(Kind.Int));
         append(new SPARCBitManipulationOp(BSF, result, asAllocatable(operand), this));
         return result;
     }
 
     @Override
     public Value emitBitScanReverse(Value operand) {
-        Variable result = newVariable(LIRKind.value(Kind.Int));
+        Variable result = newVariable(LIRKind.derive(operand).changeType(Kind.Int));
         if (operand.getKind().getStackKind() == Kind.Int) {
             append(new SPARCBitManipulationOp(IBSR, result, asAllocatable(operand), this));
         } else {
@@ -395,49 +395,49 @@
 
     @Override
     public Value emitMathAbs(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new BinaryRegConst(DAND, result, asAllocatable(input), Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL))));
         return result;
     }
 
     @Override
     public Value emitMathSqrt(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new SPARCMathIntrinsicOp(SQRT, result, asAllocatable(input)));
         return result;
     }
 
     @Override
     public Value emitMathLog(Value input, boolean base10) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new SPARCMathIntrinsicOp(LOG, result, asAllocatable(input)));
         return result;
     }
 
     @Override
     public Value emitMathCos(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new SPARCMathIntrinsicOp(COS, result, asAllocatable(input)));
         return result;
     }
 
     @Override
     public Value emitMathSin(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new SPARCMathIntrinsicOp(SIN, result, asAllocatable(input)));
         return result;
     }
 
     @Override
     public Value emitMathTan(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new SPARCMathIntrinsicOp(TAN, result, asAllocatable(input)));
         return result;
     }
 
     @Override
     public Value emitByteSwap(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         append(new SPARCByteSwapOp(result, input));
         return result;
     }
@@ -450,7 +450,7 @@
 
     @Override
     public Value emitNegate(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind().getStackKind()) {
             case Long:
                 append(new Op1Stack(LNEG, result, input));
@@ -472,7 +472,7 @@
 
     @Override
     public Value emitNot(Value input) {
-        Variable result = newVariable(input.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(input));
         switch (input.getKind().getStackKind()) {
             case Int:
                 append(new Op1Stack(INOT, result, input));
@@ -511,7 +511,7 @@
             case IMUL:
             case LMUL:
                 if (NumUtil.isInt(b.asLong())) {
-                    Variable result = newVariable(a.getLIRKind());
+                    Variable result = newVariable(LIRKind.derive(a, b));
                     append(new BinaryRegConst(op, result, a, b));
                     return result;
                 }
@@ -522,7 +522,7 @@
     }
 
     private Variable emitBinaryVar(SPARCArithmetic op, boolean commutative, AllocatableValue a, AllocatableValue b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         if (commutative) {
             append(new BinaryCommutative(op, result, a, b));
         } else {
@@ -549,7 +549,7 @@
 
     @Override
     public Variable emitSub(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind().getStackKind()) {
             case Int:
                 append(new Op2Stack(ISUB, result, a, loadNonConst(b)));
@@ -571,7 +571,7 @@
 
     @Override
     public Variable emitMul(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind().getStackKind()) {
             case Int:
                 append(new BinaryRegReg(IMUL, result, a, loadNonConst(b)));
@@ -603,7 +603,7 @@
 
     @Override
     public Value emitDiv(Value a, Value b, LIRFrameState state) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind().getStackKind()) {
             case Int:
                 append(new BinaryRegReg(IDIV, result, a, loadNonConst(b)));
@@ -625,7 +625,7 @@
 
     @Override
     public Value emitRem(Value a, Value b, LIRFrameState state) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         Variable q = null;
         switch (a.getKind().getStackKind()) {
             case Int:
@@ -688,7 +688,7 @@
 
     @Override
     public Variable emitAnd(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind().getStackKind()) {
             case Int:
                 append(new Op2Stack(IAND, result, a, loadNonConst(b)));
@@ -705,7 +705,7 @@
 
     @Override
     public Variable emitOr(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind().getStackKind()) {
             case Int:
                 append(new Op2Stack(IOR, result, a, loadNonConst(b)));
@@ -721,7 +721,7 @@
 
     @Override
     public Variable emitXor(Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b));
         switch (a.getKind().getStackKind()) {
             case Int:
                 append(new Op2Stack(IXOR, result, a, loadNonConst(b)));
@@ -736,7 +736,7 @@
     }
 
     private Variable emitShift(SPARCArithmetic op, Value a, Value b) {
-        Variable result = newVariable(a.getLIRKind());
+        Variable result = newVariable(LIRKind.derive(a, b).changeType(a.getPlatformKind()));
         AllocatableValue input = asAllocatable(a);
         if (isConstant(b)) {
             append(new BinaryRegConst(op, result, input, asConstant(b)));
@@ -802,14 +802,14 @@
         SPARCArithmetic conversionInstruction = null;
         switch (op) {
             case D2F:
-                return emitConvert2Op(LIRKind.value(Kind.Float), D2F, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), D2F, input);
             case D2I:
                 fromRegisterKind = Kind.Double;
                 toRegisterKind = Kind.Int;
                 conversionInstruction = D2I;
                 break;
             case F2L:
-                Variable v = newVariable(LIRKind.value(Kind.Double));
+                Variable v = newVariable(LIRKind.derive(inputVal).changeType(Kind.Double));
                 emitMove(v, input);
                 input = v;
             case D2L:
@@ -818,26 +818,26 @@
                 conversionInstruction = D2L;
                 break;
             case F2D:
-                return emitConvert2Op(LIRKind.value(Kind.Double), F2D, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), F2D, input);
             case F2I:
                 fromRegisterKind = Kind.Float;
                 toRegisterKind = Kind.Int;
                 conversionInstruction = F2I;
                 break;
             case I2D:
-                return emitConvert2Op(LIRKind.value(Kind.Double), I2D, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), I2D, input);
             case I2F:
-                return emitConvert2Op(LIRKind.value(Kind.Float), I2F, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), I2F, input);
             case L2D:
-                return emitConvert2Op(LIRKind.value(Kind.Double), L2D, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), L2D, input);
             case L2F:
-                return emitConvert2Op(LIRKind.value(Kind.Float), L2F, input);
+                return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), L2F, input);
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
         if (fromRegisterKind != null) {
-            AllocatableValue var = newVariable(LIRKind.value(toRegisterKind));
-            emitMove(var, emitConvert2Op(LIRKind.value(fromRegisterKind), conversionInstruction, input));
+            AllocatableValue var = newVariable(LIRKind.derive(inputVal).changeType(toRegisterKind));
+            emitMove(var, emitConvert2Op(LIRKind.derive(inputVal).changeType(fromRegisterKind), conversionInstruction, input));
             return var;
         } else {
             throw GraalInternalError.shouldNotReachHere();
@@ -847,7 +847,7 @@
     @Override
     public Value emitNarrow(Value inputVal, int bits) {
         if (inputVal.getKind() == Kind.Long && bits <= 32) {
-            return emitConvert2Op(LIRKind.value(Kind.Int), L2I, asAllocatable(inputVal));
+            return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Int), L2I, asAllocatable(inputVal));
         } else {
             return inputVal;
         }
@@ -862,11 +862,11 @@
             // sign extend to 64 bits
             switch (fromBits) {
                 case 8:
-                    return emitConvert2Op(LIRKind.value(Kind.Long), B2L, asAllocatable(inputVal));
+                    return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Long), B2L, asAllocatable(inputVal));
                 case 16:
-                    return emitConvert2Op(LIRKind.value(Kind.Long), S2L, asAllocatable(inputVal));
+                    return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Long), S2L, asAllocatable(inputVal));
                 case 32:
-                    return emitConvert2Op(LIRKind.value(Kind.Long), I2L, asAllocatable(inputVal));
+                    return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Long), I2L, asAllocatable(inputVal));
                 default:
                     throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
             }
@@ -874,9 +874,9 @@
             // sign extend to 32 bits (smaller values are internally represented as 32 bit values)
             switch (fromBits) {
                 case 8:
-                    return emitConvert2Op(LIRKind.value(Kind.Int), B2I, asAllocatable(inputVal));
+                    return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Int), B2I, asAllocatable(inputVal));
                 case 16:
-                    return emitConvert2Op(LIRKind.value(Kind.Int), S2I, asAllocatable(inputVal));
+                    return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Int), S2I, asAllocatable(inputVal));
                 case 32:
                     return inputVal;
                 default:
@@ -892,24 +892,24 @@
             return inputVal;
         } else if (fromBits > 32) {
             assert inputVal.getKind() == Kind.Long;
-            Variable result = newVariable(LIRKind.value(Kind.Long));
+            Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
             long mask = IntegerStamp.defaultMask(fromBits);
             append(new BinaryRegConst(SPARCArithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask)));
             return result;
         } else {
             assert inputVal.getKind() == Kind.Int || inputVal.getKind() == Kind.Short || inputVal.getKind() == Kind.Byte : inputVal.getKind();
-            Variable result = newVariable(LIRKind.value(Kind.Int));
+            Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int));
             int mask = (int) IntegerStamp.defaultMask(fromBits);
             Constant constant = Constant.forInt(mask);
             if (canInlineConstant(constant)) {
                 append(new BinaryRegConst(SPARCArithmetic.IAND, result, asAllocatable(inputVal), constant));
             } else {
-                Variable maskVar = newVariable(LIRKind.value(Kind.Int));
+                Variable maskVar = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int));
                 emitMove(maskVar, constant);
                 append(new BinaryRegReg(IAND, result, maskVar, (inputVal)));
             }
             if (toBits > 32) {
-                Variable longResult = newVariable(LIRKind.value(Kind.Long));
+                Variable longResult = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
                 emitMove(longResult, result);
                 return longResult;
             } else {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Tue Jul 01 15:37:38 2014 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Tue Jul 01 16:06:17 2014 +0200
@@ -350,9 +350,7 @@
         @Use({REG}) public AllocatableValue x;
         @Use({REG, STACK}) public AllocatableValue y;
 
-        public MulHighOp(AMD64Arithmetic opcode, AllocatableValue y) {
-            LIRKind kind = y.getLIRKind();
-
+        public MulHighOp(AMD64Arithmetic opcode, LIRKind kind, AllocatableValue y) {
             this.opcode = opcode;
             this.x = AMD64.rax.asValue(kind);
             this.y = y;
@@ -403,16 +401,16 @@
     public static class DivRemOp extends AMD64LIRInstruction {
 
         @Opcode private final AMD64Arithmetic opcode;
-        @Def protected AllocatableValue divResult;
-        @Def protected AllocatableValue remResult;
+        @Def public AllocatableValue divResult;
+        @Def public AllocatableValue remResult;
         @Use protected AllocatableValue x;
         @Alive protected AllocatableValue y;
         @State protected LIRFrameState state;
 
         public DivRemOp(AMD64Arithmetic opcode, AllocatableValue x, AllocatableValue y, LIRFrameState state) {
             this.opcode = opcode;
-            this.divResult = AMD64.rax.asValue(x.getLIRKind());
-            this.remResult = AMD64.rdx.asValue(x.getLIRKind());
+            this.divResult = AMD64.rax.asValue(LIRKind.derive(x, y));
+            this.remResult = AMD64.rdx.asValue(LIRKind.derive(x, y));
             this.x = x;
             this.y = y;
             this.state = state;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue Jul 01 15:37:38 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue Jul 01 16:06:17 2014 +0200
@@ -251,8 +251,8 @@
             this.result = result;
             this.x = x;
             this.y = y;
-            this.scratch1 = gen.newVariable(x.getLIRKind());
-            this.scratch2 = gen.newVariable(x.getLIRKind());
+            this.scratch1 = gen.newVariable(LIRKind.derive(x, y));
+            this.scratch2 = gen.newVariable(LIRKind.derive(x, y));
             this.state = state;
         }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Tue Jul 01 15:37:38 2014 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Tue Jul 01 16:06:17 2014 +0200
@@ -62,7 +62,7 @@
         this.result = result;
         this.input = input;
         if (opcode == IntrinsicOpcode.IBSR || opcode == IntrinsicOpcode.LBSR) {
-            scratch = gen.newVariable(input.getLIRKind());
+            scratch = gen.newVariable(LIRKind.derive(input));
         }
     }
 
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Tue Jul 01 15:37:38 2014 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Tue Jul 01 16:06:17 2014 +0200
@@ -71,13 +71,15 @@
         assert getKind() != input.getKind();
         assert generator.getLIRGeneratorTool().target().getSizeInBytes(getKind()) == generator.getLIRGeneratorTool().target().getSizeInBytes(input.getKind());
 
+        Value value = generator.operand(input);
         LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
         if (kind.isValue()) {
-            kind = kind.makeDerivedReference();
+            // only add reference information, but never drop it
+            kind = value.getLIRKind().changeType(kind.getPlatformKind());
         }
 
         AllocatableValue result = generator.getLIRGeneratorTool().newVariable(kind);
-        generator.getLIRGeneratorTool().emitMove(result, generator.operand(input));
+        generator.getLIRGeneratorTool().emitMove(result, value);
         generator.setResult(this, result);
     }
 }