OSDN Git Service

ART: Prevent float inference back to SSA in-regs.
authorStephen Kyle <stephen.kyle@arm.com>
Thu, 16 Oct 2014 14:02:42 +0000 (15:02 +0100)
committerIan Rogers <irogers@google.com>
Fri, 24 Oct 2014 21:40:22 +0000 (14:40 -0700)
commit8fe0e35c546921a3576411948efffb3c813ef686
tree96cfa612a25dcf567d84d76f13c145339c17d73b
parent98c271d517bc4d25fc6879b4b8e35ea93885d9e2
ART: Prevent float inference back to SSA in-regs.

.method public static getInt(I)I
    .registers 2
    const/4 v0, 0x0
    if-ne v0, v0, :after
    float-to-int v0, v0
    :exit
    add-int/2addr v0, v1
    return v0
    :after
    move v1, v0
    goto :exit
.end method

In this code sample, v1 is the single parameter to this method. In one
of the phi-nodes inserted between :exit and add-int/2addr, v1's two
incoming SSA regs are:
  - the initial def of v1 as a parameter
  - the v1 def'd at move v1, v0.
During type inference, because the 2nd def is a float (because of the
earlier float-to-int v0, v0) this will change the type of the 1st def to a
float as well, which is incorrect since the first parameter is known to be
non-float.

This fix checks during phi-node type-inference if an SSA reg that is the
initial def of a parameter vreg is about to be set as float when it was
not previously, and skips the inference if so.

In this case, when using a hard-float ABI, having the in-reg v1 set as
float causes FlushIns() to read the argument to the method from an FP reg,
when the argument will be passed in a core reg by any caller.

Also included is a smali test for this bug: compare difference between
./run-test --64 800
./run-test --64 --interpreter 800
when the vreg_analysis patch has not been applied.
(Requires 64-bit because 32-bit ARM currently does not use hard-float.)

getInt(I)I should return its argument, but it returns an incorrect
value.

Change-Id: I1d4b5be6a931fe853279e89dd820820f29823da1
Signed-off-by: Stephen Kyle <stephen.kyle@arm.com>
compiler/dex/vreg_analysis.cc
test/800-smali/expected.txt
test/800-smali/smali/FloatBadArgReg.smali [new file with mode: 0644]
test/800-smali/src/Main.java