[llvm] r219187 - [FastISel][AArch64] Teach the address computation code to also fold sign-/zero-extends.
Juergen Ributzka
juergen at apple.com
Mon Oct 6 20:40:06 PDT 2014
Author: ributzka
Date: Mon Oct 6 22:40:06 2014
New Revision: 219187
URL: http://llvm.org/viewvc/llvm-project?rev=219187&view=rev
Log:
[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.
Modified:
llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
llvm/trunk/test/CodeGen/AArch64/fast-isel-int-ext.ll
Modified: llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=219187&r1=219186&r2=219187&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp Mon Oct 6 22:40:06 2014
@@ -776,6 +776,35 @@ bool AArch64FastISel::computeAddress(con
}
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
if (Addr.getReg()) {
Modified: llvm/trunk/test/CodeGen/AArch64/fast-isel-int-ext.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/fast-isel-int-ext.ll?rev=219187&r1=219186&r2=219187&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/fast-isel-int-ext.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/fast-isel-int-ext.ll Mon Oct 6 22:40:06 2014
@@ -371,8 +371,7 @@ define i64 @load_register_sext_i32_to_i6
; Extend
define i32 @load_extend_zext_i8_to_i32(i64 %a, i32 %b) {
; CHECK-LABEL: load_extend_zext_i8_to_i32
-; CHECK: sxtw [[REG:x[0-9]+]], w1
-; CHECK-NEXT: ldrb w0, [x0, [[REG]]]
+; CHECK: ldrb w0, [x0, w1, sxtw]
; CHECK-NOT: uxtb
%1 = sext i32 %b to i64
%2 = add i64 %a, %1
@@ -384,8 +383,7 @@ define i32 @load_extend_zext_i8_to_i32(i
define i32 @load_extend_zext_i16_to_i32(i64 %a, i32 %b) {
; CHECK-LABEL: load_extend_zext_i16_to_i32
-; CHECK: sxtw [[REG:x[0-9]+]], w1
-; CHECK-NEXT: ldrh w0, [x0, [[REG]]]
+; CHECK: ldrh w0, [x0, w1, sxtw]
; CHECK-NOT: uxth
%1 = sext i32 %b to i64
%2 = add i64 %a, %1
@@ -397,8 +395,7 @@ define i32 @load_extend_zext_i16_to_i32(
define i64 @load_extend_zext_i8_to_i64(i64 %a, i32 %b) {
; CHECK-LABEL: load_extend_zext_i8_to_i64
-; CHECK: sxtw [[REG:x[0-9]+]], w1
-; CHECK-NEXT: ldrb w0, [x0, [[REG]]]
+; CHECK: ldrb w0, [x0, w1, sxtw]
; CHECK-NOT: uxtb
%1 = sext i32 %b to i64
%2 = add i64 %a, %1
@@ -410,8 +407,7 @@ define i64 @load_extend_zext_i8_to_i64(i
define i64 @load_extend_zext_i16_to_i64(i64 %a, i32 %b) {
; CHECK-LABEL: load_extend_zext_i16_to_i64
-; CHECK: sxtw [[REG:x[0-9]+]], w1
-; CHECK-NEXT: ldrh w0, [x0, [[REG]]]
+; CHECK: ldrh w0, [x0, w1, sxtw]
; CHECK-NOT: uxth
%1 = sext i32 %b to i64
%2 = add i64 %a, %1
@@ -423,8 +419,7 @@ define i64 @load_extend_zext_i16_to_i64(
define i64 @load_extend_zext_i32_to_i64(i64 %a, i32 %b) {
; CHECK-LABEL: load_extend_zext_i32_to_i64
-; CHECK: sxtw [[REG:x[0-9]+]], w1
-; CHECK-NEXT: ldr w0, [x0, [[REG]]]
+; CHECK: ldr w0, [x0, w1, sxtw]
; CHECK-NOT: uxtw
%1 = sext i32 %b to i64
%2 = add i64 %a, %1
@@ -436,8 +431,7 @@ define i64 @load_extend_zext_i32_to_i64(
define i32 @load_extend_sext_i8_to_i32(i64 %a, i32 %b) {
; CHECK-LABEL: load_extend_sext_i8_to_i32
-; CHECK: sxtw [[REG:x[0-9]+]], w1
-; CHECK-NEXT: ldrsb w0, [x0, [[REG]]]
+; CHECK: ldrsb w0, [x0, w1, sxtw]
; CHECK-NOT: sxtb
%1 = sext i32 %b to i64
%2 = add i64 %a, %1
@@ -449,8 +443,7 @@ define i32 @load_extend_sext_i8_to_i32(i
define i32 @load_extend_sext_i16_to_i32(i64 %a, i32 %b) {
; CHECK-LABEL: load_extend_sext_i16_to_i32
-; CHECK: sxtw [[REG:x[0-9]+]], w1
-; CHECK-NEXT: ldrsh w0, [x0, [[REG]]]
+; CHECK: ldrsh w0, [x0, w1, sxtw]
; CHECK-NOT: sxth
%1 = sext i32 %b to i64
%2 = add i64 %a, %1
@@ -462,8 +455,7 @@ define i32 @load_extend_sext_i16_to_i32(
define i64 @load_extend_sext_i8_to_i64(i64 %a, i32 %b) {
; CHECK-LABEL: load_extend_sext_i8_to_i64
-; CHECK: sxtw [[REG:x[0-9]+]], w1
-; CHECK-NEXT: ldrsb x0, [x0, [[REG]]]
+; CHECK: ldrsb x0, [x0, w1, sxtw]
; CHECK-NOT: sxtb
%1 = sext i32 %b to i64
%2 = add i64 %a, %1
@@ -475,8 +467,7 @@ define i64 @load_extend_sext_i8_to_i64(i
define i64 @load_extend_sext_i16_to_i64(i64 %a, i32 %b) {
; CHECK-LABEL: load_extend_sext_i16_to_i64
-; CHECK: sxtw [[REG:x[0-9]+]], w1
-; CHECK-NEXT: ldrsh x0, [x0, [[REG]]]
+; CHECK: ldrsh x0, [x0, w1, sxtw]
; CHECK-NOT: sxth
%1 = sext i32 %b to i64
%2 = add i64 %a, %1
@@ -488,8 +479,7 @@ define i64 @load_extend_sext_i16_to_i64(
define i64 @load_extend_sext_i32_to_i64(i64 %a, i32 %b) {
; CHECK-LABEL: load_extend_sext_i32_to_i64
-; CHECK: sxtw [[REG:x[0-9]+]], w1
-; CHECK-NEXT: ldrsw x0, [x0, [[REG]]]
+; CHECK: ldrsw x0, [x0, w1, sxtw]
; CHECK-NOT: sxtw
%1 = sext i32 %b to i64
%2 = add i64 %a, %1
More information about the llvm-commits
mailing list