diff options
author | buzbee <buzbee@google.com> | 2014-10-03 13:14:17 -0700 |
---|---|---|
committer | buzbee <buzbee@google.com> | 2014-10-03 13:14:17 -0700 |
commit | 7c02e918e752ab36f0b6cab7528f10c0cf55a4ee (patch) | |
tree | 704cb9845bbdecc977c8fb31dc0a677450d17303 /compiler/dex/quick/gen_invoke.cc | |
parent | b5325e24ca58299b2b011e57e784b2584f99d687 (diff) | |
download | android_art-7c02e918e752ab36f0b6cab7528f10c0cf55a4ee.tar.gz android_art-7c02e918e752ab36f0b6cab7528f10c0cf55a4ee.tar.bz2 android_art-7c02e918e752ab36f0b6cab7528f10c0cf55a4ee.zip |
Quick compiler: Fix ambiguous LoadValue()
Internal b/17790197 & hat tip to Stephen Kyle
The following custom-edited dex program demonstrated
incorrect code generation caused by type confusion.
In the example, the constant held in v0 is used in both
float and int contexts, and the register class gets
confused at the if-eq.
.method private static getInt()I
.registers 4
const/16 v0, 100
const/4 v1, 1
const/4 v2, 7
:loop
if-eq v2, v0, :done
add-int v2, v2, v1
goto :loop
:done
add-float v3, v0, v1
return v2
.end method
The bug was introduced in c/96499, "Quick compiler: reference cleanup"
That CL created a convenience variant of LoadValue which selected the
target register type based on the type of the RegLocation. It should
not have done so. The type of a RegLocation is the compiler's best
guess of the Dalvik type - and Dalvik allows constants to be used
in multiple type contexts. All code generation utilities must specify
desired register class based on the capabilities of the instructions
to be emitted. In the failing case, OpCmpImmBranch (and
GenCompareZeroAndBranch) will be using core registers, so the
LoadValue must specify either kCoreReg or kRefReg.
The CL deletes the dangerous LoadValue() variant.
Change-Id: Ie4ec6e51b19676dbbb9628c72c8b3473a419e7ec
Diffstat (limited to 'compiler/dex/quick/gen_invoke.cc')
-rwxr-xr-x | compiler/dex/quick/gen_invoke.cc | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index c308932bcf..bafb57d60e 100755 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -1643,7 +1643,7 @@ bool Mir2Lir::GenInlinedUnsafePut(CallInfo* info, bool is_long, FreeTemp(rl_temp_offset); } } else { - rl_value = LoadValue(rl_src_value); + rl_value = LoadValue(rl_src_value, LocToRegClass(rl_src_value)); if (rl_value.ref) { StoreRefIndexed(rl_object.reg, rl_offset.reg, rl_value.reg, 0); } else { |