[FastISel][AArch64] Teach the address computation to also fold sub instructions.
authorJuergen Ributzka <juergen@apple.com>
Tue, 7 Oct 2014 03:40:03 +0000 (03:40 +0000)
committerJuergen Ributzka <juergen@apple.com>
Tue, 7 Oct 2014 03:40:03 +0000 (03:40 +0000)
Tiny enhancement to the address computation code to also fold sub instructions
if the rhs is constant and can be folded into the offset.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219186 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64FastISel.cpp
test/CodeGen/AArch64/fast-isel-int-ext.ll

index 504049bbafd5df51232d8be29196c351672f1795..559a6bdf8ea804527c3419d4137cc2337f31c29e 100644 (file)
@@ -590,7 +590,7 @@ bool AArch64FastISel::computeAddress(const Value *Obj, Address &Addr, Type *Ty)
       std::swap(LHS, RHS);
 
     if (const ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
-      Addr.setOffset(Addr.getOffset() + (uint64_t)CI->getSExtValue());
+      Addr.setOffset(Addr.getOffset() + CI->getSExtValue());
       return computeAddress(LHS, Addr, Ty);
     }
 
@@ -601,6 +601,17 @@ bool AArch64FastISel::computeAddress(const Value *Obj, Address &Addr, Type *Ty)
 
     break;
   }
+  case Instruction::Sub: {
+    // Subs of constants are common and easy enough.
+    const Value *LHS = U->getOperand(0);
+    const Value *RHS = U->getOperand(1);
+
+    if (const ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
+      Addr.setOffset(Addr.getOffset() - CI->getSExtValue());
+      return computeAddress(LHS, Addr, Ty);
+    }
+    break;
+  }
   case Instruction::Shl: {
     if (Addr.getOffsetReg())
       break;
index 31372ee35bd9e39de5c0c8ef5dc86c3bca9812bc..4a783a87a70a8dad2cf9a0709feaf21ae04653c0 100644 (file)
@@ -151,7 +151,7 @@ define i32 @load_unscaled_zext_i8_to_i32(i64 %a) {
 ; CHECK-LABEL: load_unscaled_zext_i8_to_i32
 ; CHECK:       ldurb w0, [x0, #-8]
 ; CHECK-NOT:   uxtb
-  %1 = add i64 %a, -8
+  %1 = sub i64 %a, 8
   %2 = inttoptr i64 %1 to i8*
   %3 = load i8* %2
   %4 = zext i8 %3 to i32
@@ -162,7 +162,7 @@ define i32 @load_unscaled_zext_i16_to_i32(i64 %a) {
 ; CHECK-LABEL: load_unscaled_zext_i16_to_i32
 ; CHECK:       ldurh w0, [x0, #-8]
 ; CHECK-NOT:   uxth
-  %1 = add i64 %a, -8
+  %1 = sub i64 %a, 8
   %2 = inttoptr i64 %1 to i16*
   %3 = load i16* %2
   %4 = zext i16 %3 to i32
@@ -173,7 +173,7 @@ define i64 @load_unscaled_zext_i8_to_i64(i64 %a) {
 ; CHECK-LABEL: load_unscaled_zext_i8_to_i64
 ; CHECK:       ldurb w0, [x0, #-8]
 ; CHECK-NOT:   uxtb
-  %1 = add i64 %a, -8
+  %1 = sub i64 %a, 8
   %2 = inttoptr i64 %1 to i8*
   %3 = load i8* %2
   %4 = zext i8 %3 to i64
@@ -184,7 +184,7 @@ define i64 @load_unscaled_zext_i16_to_i64(i64 %a) {
 ; CHECK-LABEL: load_unscaled_zext_i16_to_i64
 ; CHECK:       ldurh w0, [x0, #-8]
 ; CHECK-NOT:   uxth
-  %1 = add i64 %a, -8
+  %1 = sub i64 %a, 8
   %2 = inttoptr i64 %1 to i16*
   %3 = load i16* %2
   %4 = zext i16 %3 to i64
@@ -195,7 +195,7 @@ define i64 @load_unscaled_zext_i32_to_i64(i64 %a) {
 ; CHECK-LABEL: load_unscaled_zext_i32_to_i64
 ; CHECK:       ldur w0, [x0, #-8]
 ; CHECK-NOT:   uxtw
-  %1 = add i64 %a, -8
+  %1 = sub i64 %a, 8
   %2 = inttoptr i64 %1 to i32*
   %3 = load i32* %2
   %4 = zext i32 %3 to i64
@@ -206,7 +206,7 @@ define i32 @load_unscaled_sext_i8_to_i32(i64 %a) {
 ; CHECK-LABEL: load_unscaled_sext_i8_to_i32
 ; CHECK:       ldursb w0, [x0, #-8]
 ; CHECK-NOT:   sxtb
-  %1 = add i64 %a, -8
+  %1 = sub i64 %a, 8
   %2 = inttoptr i64 %1 to i8*
   %3 = load i8* %2
   %4 = sext i8 %3 to i32
@@ -217,7 +217,7 @@ define i32 @load_unscaled_sext_i16_to_i32(i64 %a) {
 ; CHECK-LABEL: load_unscaled_sext_i16_to_i32
 ; CHECK:       ldursh w0, [x0, #-8]
 ; CHECK-NOT:   sxth
-  %1 = add i64 %a, -8
+  %1 = sub i64 %a, 8
   %2 = inttoptr i64 %1 to i16*
   %3 = load i16* %2
   %4 = sext i16 %3 to i32
@@ -228,7 +228,7 @@ define i64 @load_unscaled_sext_i8_to_i64(i64 %a) {
 ; CHECK-LABEL: load_unscaled_sext_i8_to_i64
 ; CHECK:       ldursb x0, [x0, #-8]
 ; CHECK-NOT:   sxtb
-  %1 = add i64 %a, -8
+  %1 = sub i64 %a, 8
   %2 = inttoptr i64 %1 to i8*
   %3 = load i8* %2
   %4 = sext i8 %3 to i64
@@ -239,7 +239,7 @@ define i64 @load_unscaled_sext_i16_to_i64(i64 %a) {
 ; CHECK-LABEL: load_unscaled_sext_i16_to_i64
 ; CHECK:       ldursh x0, [x0, #-8]
 ; CHECK-NOT:   sxth
-  %1 = add i64 %a, -8
+  %1 = sub i64 %a, 8
   %2 = inttoptr i64 %1 to i16*
   %3 = load i16* %2
   %4 = sext i16 %3 to i64
@@ -250,7 +250,7 @@ define i64 @load_unscaled_sext_i32_to_i64(i64 %a) {
 ; CHECK-LABEL: load_unscaled_sext_i32_to_i64
 ; CHECK:       ldursw x0, [x0, #-8]
 ; CHECK-NOT:   sxtw
-  %1 = add i64 %a, -8
+  %1 = sub i64 %a, 8
   %2 = inttoptr i64 %1 to i32*
   %3 = load i32* %2
   %4 = sext i32 %3 to i64