mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-11 13:37:07 +00:00
[AArch64][FastISel] Fix integer extend optimization.
The integer extend optimization tries to fold the extend into the load instruction. This requires us to identify if the extend has already been emitted or not and act accordingly on it. The check that was originally performed for this was not sufficient. Besides checking the ValueMap for a mapped register we also need to check if the virtual register has already an associated machine instruction that defines it. This fixes rdar://problem/20470788. llvm-svn: 234529
This commit is contained in:
parent
d618af519a
commit
6f558fd68f
@ -1917,7 +1917,8 @@ bool AArch64FastISel::selectLoad(const Instruction *I) {
|
|||||||
// could select it. Emit a copy to subreg if necessary. FastISel will remove
|
// could select it. Emit a copy to subreg if necessary. FastISel will remove
|
||||||
// it when it selects the integer extend.
|
// it when it selects the integer extend.
|
||||||
unsigned Reg = lookUpRegForValue(IntExtVal);
|
unsigned Reg = lookUpRegForValue(IntExtVal);
|
||||||
if (!Reg) {
|
auto *MI = MRI.getUniqueVRegDef(Reg);
|
||||||
|
if (!MI) {
|
||||||
if (RetVT == MVT::i64 && VT <= MVT::i32) {
|
if (RetVT == MVT::i64 && VT <= MVT::i32) {
|
||||||
if (WantZExt) {
|
if (WantZExt) {
|
||||||
// Delete the last emitted instruction from emitLoad (SUBREG_TO_REG).
|
// Delete the last emitted instruction from emitLoad (SUBREG_TO_REG).
|
||||||
@ -1935,10 +1936,7 @@ bool AArch64FastISel::selectLoad(const Instruction *I) {
|
|||||||
// The integer extend has already been emitted - delete all the instructions
|
// The integer extend has already been emitted - delete all the instructions
|
||||||
// that have been emitted by the integer extend lowering code and use the
|
// that have been emitted by the integer extend lowering code and use the
|
||||||
// result from the load instruction directly.
|
// result from the load instruction directly.
|
||||||
while (Reg) {
|
while (MI) {
|
||||||
auto *MI = MRI.getUniqueVRegDef(Reg);
|
|
||||||
if (!MI)
|
|
||||||
break;
|
|
||||||
Reg = 0;
|
Reg = 0;
|
||||||
for (auto &Opnd : MI->uses()) {
|
for (auto &Opnd : MI->uses()) {
|
||||||
if (Opnd.isReg()) {
|
if (Opnd.isReg()) {
|
||||||
@ -1947,6 +1945,9 @@ bool AArch64FastISel::selectLoad(const Instruction *I) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
MI->eraseFromParent();
|
MI->eraseFromParent();
|
||||||
|
MI = nullptr;
|
||||||
|
if (Reg)
|
||||||
|
MI = MRI.getUniqueVRegDef(Reg);
|
||||||
}
|
}
|
||||||
updateValueMap(IntExtVal, ResultReg);
|
updateValueMap(IntExtVal, ResultReg);
|
||||||
return true;
|
return true;
|
||||||
|
19
test/CodeGen/AArch64/fast-isel-int-ext5.ll
Normal file
19
test/CodeGen/AArch64/fast-isel-int-ext5.ll
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
; RUN: llc -mtriple=aarch64-apple-darwin -O0 -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK-LABEL: int_ext_opt
|
||||||
|
define i64 @int_ext_opt(i8* %addr, i1 %c1, i1 %c2) {
|
||||||
|
entry:
|
||||||
|
%0 = load i8, i8* %addr
|
||||||
|
br i1 %c1, label %bb1, label %bb2
|
||||||
|
|
||||||
|
bb1:
|
||||||
|
%1 = zext i8 %0 to i64
|
||||||
|
br i1 %c2, label %bb2, label %exit
|
||||||
|
|
||||||
|
bb2:
|
||||||
|
%2 = phi i64 [1, %entry], [%1, %bb1]
|
||||||
|
ret i64 %2
|
||||||
|
|
||||||
|
exit:
|
||||||
|
ret i64 0
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user