mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-04 05:31:51 +00:00
[FastISel][AArch64] Teach the address computation code to also fold sign-/zero-extends.
The code already folds sign-/zero-extends, but only if they are arguments to mul and shift instructions. This extends the code to also fold them when they are direct inputs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219187 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3692081566
commit
301d3d04f0
@ -776,6 +776,35 @@ bool AArch64FastISel::computeAddress(const Value *Obj, Address &Addr, Type *Ty)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Instruction::SExt:
|
||||||
|
case Instruction::ZExt: {
|
||||||
|
if (!Addr.getReg() || Addr.getOffsetReg())
|
||||||
|
break;
|
||||||
|
|
||||||
|
const Value *Src = nullptr;
|
||||||
|
// Fold the zext or sext when it won't become a noop.
|
||||||
|
if (const auto *ZE = dyn_cast<ZExtInst>(U)) {
|
||||||
|
if (!isIntExtFree(ZE) && ZE->getOperand(0)->getType()->isIntegerTy(32)) {
|
||||||
|
Addr.setExtendType(AArch64_AM::UXTW);
|
||||||
|
Src = ZE->getOperand(0);
|
||||||
|
}
|
||||||
|
} else if (const auto *SE = dyn_cast<SExtInst>(U)) {
|
||||||
|
if (!isIntExtFree(SE) && SE->getOperand(0)->getType()->isIntegerTy(32)) {
|
||||||
|
Addr.setExtendType(AArch64_AM::SXTW);
|
||||||
|
Src = SE->getOperand(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Src)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Addr.setShift(0);
|
||||||
|
unsigned Reg = getRegForValue(Src);
|
||||||
|
if (!Reg)
|
||||||
|
return false;
|
||||||
|
Addr.setOffsetReg(Reg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} // end switch
|
} // end switch
|
||||||
|
|
||||||
if (Addr.getReg()) {
|
if (Addr.getReg()) {
|
||||||
|
@ -371,8 +371,7 @@ define i64 @load_register_sext_i32_to_i64(i64 %a, i64 %b) {
|
|||||||
; Extend
|
; Extend
|
||||||
define i32 @load_extend_zext_i8_to_i32(i64 %a, i32 %b) {
|
define i32 @load_extend_zext_i8_to_i32(i64 %a, i32 %b) {
|
||||||
; CHECK-LABEL: load_extend_zext_i8_to_i32
|
; CHECK-LABEL: load_extend_zext_i8_to_i32
|
||||||
; CHECK: sxtw [[REG:x[0-9]+]], w1
|
; CHECK: ldrb w0, [x0, w1, sxtw]
|
||||||
; CHECK-NEXT: ldrb w0, [x0, [[REG]]]
|
|
||||||
; CHECK-NOT: uxtb
|
; CHECK-NOT: uxtb
|
||||||
%1 = sext i32 %b to i64
|
%1 = sext i32 %b to i64
|
||||||
%2 = add i64 %a, %1
|
%2 = add i64 %a, %1
|
||||||
@ -384,8 +383,7 @@ define i32 @load_extend_zext_i8_to_i32(i64 %a, i32 %b) {
|
|||||||
|
|
||||||
define i32 @load_extend_zext_i16_to_i32(i64 %a, i32 %b) {
|
define i32 @load_extend_zext_i16_to_i32(i64 %a, i32 %b) {
|
||||||
; CHECK-LABEL: load_extend_zext_i16_to_i32
|
; CHECK-LABEL: load_extend_zext_i16_to_i32
|
||||||
; CHECK: sxtw [[REG:x[0-9]+]], w1
|
; CHECK: ldrh w0, [x0, w1, sxtw]
|
||||||
; CHECK-NEXT: ldrh w0, [x0, [[REG]]]
|
|
||||||
; CHECK-NOT: uxth
|
; CHECK-NOT: uxth
|
||||||
%1 = sext i32 %b to i64
|
%1 = sext i32 %b to i64
|
||||||
%2 = add i64 %a, %1
|
%2 = add i64 %a, %1
|
||||||
@ -397,8 +395,7 @@ define i32 @load_extend_zext_i16_to_i32(i64 %a, i32 %b) {
|
|||||||
|
|
||||||
define i64 @load_extend_zext_i8_to_i64(i64 %a, i32 %b) {
|
define i64 @load_extend_zext_i8_to_i64(i64 %a, i32 %b) {
|
||||||
; CHECK-LABEL: load_extend_zext_i8_to_i64
|
; CHECK-LABEL: load_extend_zext_i8_to_i64
|
||||||
; CHECK: sxtw [[REG:x[0-9]+]], w1
|
; CHECK: ldrb w0, [x0, w1, sxtw]
|
||||||
; CHECK-NEXT: ldrb w0, [x0, [[REG]]]
|
|
||||||
; CHECK-NOT: uxtb
|
; CHECK-NOT: uxtb
|
||||||
%1 = sext i32 %b to i64
|
%1 = sext i32 %b to i64
|
||||||
%2 = add i64 %a, %1
|
%2 = add i64 %a, %1
|
||||||
@ -410,8 +407,7 @@ define i64 @load_extend_zext_i8_to_i64(i64 %a, i32 %b) {
|
|||||||
|
|
||||||
define i64 @load_extend_zext_i16_to_i64(i64 %a, i32 %b) {
|
define i64 @load_extend_zext_i16_to_i64(i64 %a, i32 %b) {
|
||||||
; CHECK-LABEL: load_extend_zext_i16_to_i64
|
; CHECK-LABEL: load_extend_zext_i16_to_i64
|
||||||
; CHECK: sxtw [[REG:x[0-9]+]], w1
|
; CHECK: ldrh w0, [x0, w1, sxtw]
|
||||||
; CHECK-NEXT: ldrh w0, [x0, [[REG]]]
|
|
||||||
; CHECK-NOT: uxth
|
; CHECK-NOT: uxth
|
||||||
%1 = sext i32 %b to i64
|
%1 = sext i32 %b to i64
|
||||||
%2 = add i64 %a, %1
|
%2 = add i64 %a, %1
|
||||||
@ -423,8 +419,7 @@ define i64 @load_extend_zext_i16_to_i64(i64 %a, i32 %b) {
|
|||||||
|
|
||||||
define i64 @load_extend_zext_i32_to_i64(i64 %a, i32 %b) {
|
define i64 @load_extend_zext_i32_to_i64(i64 %a, i32 %b) {
|
||||||
; CHECK-LABEL: load_extend_zext_i32_to_i64
|
; CHECK-LABEL: load_extend_zext_i32_to_i64
|
||||||
; CHECK: sxtw [[REG:x[0-9]+]], w1
|
; CHECK: ldr w0, [x0, w1, sxtw]
|
||||||
; CHECK-NEXT: ldr w0, [x0, [[REG]]]
|
|
||||||
; CHECK-NOT: uxtw
|
; CHECK-NOT: uxtw
|
||||||
%1 = sext i32 %b to i64
|
%1 = sext i32 %b to i64
|
||||||
%2 = add i64 %a, %1
|
%2 = add i64 %a, %1
|
||||||
@ -436,8 +431,7 @@ define i64 @load_extend_zext_i32_to_i64(i64 %a, i32 %b) {
|
|||||||
|
|
||||||
define i32 @load_extend_sext_i8_to_i32(i64 %a, i32 %b) {
|
define i32 @load_extend_sext_i8_to_i32(i64 %a, i32 %b) {
|
||||||
; CHECK-LABEL: load_extend_sext_i8_to_i32
|
; CHECK-LABEL: load_extend_sext_i8_to_i32
|
||||||
; CHECK: sxtw [[REG:x[0-9]+]], w1
|
; CHECK: ldrsb w0, [x0, w1, sxtw]
|
||||||
; CHECK-NEXT: ldrsb w0, [x0, [[REG]]]
|
|
||||||
; CHECK-NOT: sxtb
|
; CHECK-NOT: sxtb
|
||||||
%1 = sext i32 %b to i64
|
%1 = sext i32 %b to i64
|
||||||
%2 = add i64 %a, %1
|
%2 = add i64 %a, %1
|
||||||
@ -449,8 +443,7 @@ define i32 @load_extend_sext_i8_to_i32(i64 %a, i32 %b) {
|
|||||||
|
|
||||||
define i32 @load_extend_sext_i16_to_i32(i64 %a, i32 %b) {
|
define i32 @load_extend_sext_i16_to_i32(i64 %a, i32 %b) {
|
||||||
; CHECK-LABEL: load_extend_sext_i16_to_i32
|
; CHECK-LABEL: load_extend_sext_i16_to_i32
|
||||||
; CHECK: sxtw [[REG:x[0-9]+]], w1
|
; CHECK: ldrsh w0, [x0, w1, sxtw]
|
||||||
; CHECK-NEXT: ldrsh w0, [x0, [[REG]]]
|
|
||||||
; CHECK-NOT: sxth
|
; CHECK-NOT: sxth
|
||||||
%1 = sext i32 %b to i64
|
%1 = sext i32 %b to i64
|
||||||
%2 = add i64 %a, %1
|
%2 = add i64 %a, %1
|
||||||
@ -462,8 +455,7 @@ define i32 @load_extend_sext_i16_to_i32(i64 %a, i32 %b) {
|
|||||||
|
|
||||||
define i64 @load_extend_sext_i8_to_i64(i64 %a, i32 %b) {
|
define i64 @load_extend_sext_i8_to_i64(i64 %a, i32 %b) {
|
||||||
; CHECK-LABEL: load_extend_sext_i8_to_i64
|
; CHECK-LABEL: load_extend_sext_i8_to_i64
|
||||||
; CHECK: sxtw [[REG:x[0-9]+]], w1
|
; CHECK: ldrsb x0, [x0, w1, sxtw]
|
||||||
; CHECK-NEXT: ldrsb x0, [x0, [[REG]]]
|
|
||||||
; CHECK-NOT: sxtb
|
; CHECK-NOT: sxtb
|
||||||
%1 = sext i32 %b to i64
|
%1 = sext i32 %b to i64
|
||||||
%2 = add i64 %a, %1
|
%2 = add i64 %a, %1
|
||||||
@ -475,8 +467,7 @@ define i64 @load_extend_sext_i8_to_i64(i64 %a, i32 %b) {
|
|||||||
|
|
||||||
define i64 @load_extend_sext_i16_to_i64(i64 %a, i32 %b) {
|
define i64 @load_extend_sext_i16_to_i64(i64 %a, i32 %b) {
|
||||||
; CHECK-LABEL: load_extend_sext_i16_to_i64
|
; CHECK-LABEL: load_extend_sext_i16_to_i64
|
||||||
; CHECK: sxtw [[REG:x[0-9]+]], w1
|
; CHECK: ldrsh x0, [x0, w1, sxtw]
|
||||||
; CHECK-NEXT: ldrsh x0, [x0, [[REG]]]
|
|
||||||
; CHECK-NOT: sxth
|
; CHECK-NOT: sxth
|
||||||
%1 = sext i32 %b to i64
|
%1 = sext i32 %b to i64
|
||||||
%2 = add i64 %a, %1
|
%2 = add i64 %a, %1
|
||||||
@ -488,8 +479,7 @@ define i64 @load_extend_sext_i16_to_i64(i64 %a, i32 %b) {
|
|||||||
|
|
||||||
define i64 @load_extend_sext_i32_to_i64(i64 %a, i32 %b) {
|
define i64 @load_extend_sext_i32_to_i64(i64 %a, i32 %b) {
|
||||||
; CHECK-LABEL: load_extend_sext_i32_to_i64
|
; CHECK-LABEL: load_extend_sext_i32_to_i64
|
||||||
; CHECK: sxtw [[REG:x[0-9]+]], w1
|
; CHECK: ldrsw x0, [x0, w1, sxtw]
|
||||||
; CHECK-NEXT: ldrsw x0, [x0, [[REG]]]
|
|
||||||
; CHECK-NOT: sxtw
|
; CHECK-NOT: sxtw
|
||||||
%1 = sext i32 %b to i64
|
%1 = sext i32 %b to i64
|
||||||
%2 = add i64 %a, %1
|
%2 = add i64 %a, %1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user