[llvm] r218161 - [FastIsel][AArch64] Fix a think-o in address computation.

Juergen Ributzka juergen at apple.com
Fri Sep 19 15:23:47 PDT 2014


Author: ributzka
Date: Fri Sep 19 17:23:46 2014
New Revision: 218161

URL: http://llvm.org/viewvc/llvm-project?rev=218161&view=rev
Log:
[FastIsel][AArch64] Fix a think-o in address computation.

When looking through sign/zero-extensions the code would always assume there is
such an extension instruction and use the wrong operand for the address.

There was also a minor issue in the handling of 'AND' instructions. I
accidentially used a 'cast' instead of a 'dyn_cast'.

Modified:
    llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
    llvm/trunk/test/CodeGen/AArch64/fast-isel-addressing-modes.ll

Modified: llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=218161&r1=218160&r2=218161&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp Fri Sep 19 17:23:46 2014
@@ -561,7 +561,7 @@ bool AArch64FastISel::computeAddress(con
 
     break;
   }
-  case Instruction::Shl:
+  case Instruction::Shl: {
     if (Addr.getOffsetReg())
       break;
 
@@ -584,19 +584,24 @@ bool AArch64FastISel::computeAddress(con
       Addr.setShift(Val);
       Addr.setExtendType(AArch64_AM::LSL);
 
-      if (const auto *I = dyn_cast<Instruction>(U->getOperand(0)))
+      const Value *Src = U->getOperand(0);
+      if (const auto *I = dyn_cast<Instruction>(Src))
         if (FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB)
-          U = I;
+          Src = I;
 
-      if (const auto *ZE = dyn_cast<ZExtInst>(U))
-        if (ZE->getOperand(0)->getType()->isIntegerTy(32))
+      if (const auto *ZE = dyn_cast<ZExtInst>(Src)) {
+        if (ZE->getOperand(0)->getType()->isIntegerTy(32)) {
           Addr.setExtendType(AArch64_AM::UXTW);
-
-      if (const auto *SE = dyn_cast<SExtInst>(U))
-        if (SE->getOperand(0)->getType()->isIntegerTy(32))
+          Src = ZE->getOperand(0);
+        }
+      } else if (const auto *SE = dyn_cast<SExtInst>(Src)) {
+        if (SE->getOperand(0)->getType()->isIntegerTy(32)) {
           Addr.setExtendType(AArch64_AM::SXTW);
+          Src = SE->getOperand(0);
+        }
+      }
 
-      if (const auto *AI = dyn_cast<BinaryOperator>(U))
+      if (const auto *AI = dyn_cast<BinaryOperator>(Src))
         if (AI->getOpcode() == Instruction::And) {
           const Value *LHS = AI->getOperand(0);
           const Value *RHS = AI->getOperand(1);
@@ -605,7 +610,7 @@ bool AArch64FastISel::computeAddress(con
             if (C->getValue() == 0xffffffff)
               std::swap(LHS, RHS);
 
-          if (const auto *C = cast<ConstantInt>(RHS))
+          if (const auto *C = dyn_cast<ConstantInt>(RHS))
             if (C->getValue() == 0xffffffff) {
               Addr.setExtendType(AArch64_AM::UXTW);
               unsigned Reg = getRegForValue(LHS);
@@ -619,13 +624,14 @@ bool AArch64FastISel::computeAddress(con
             }
         }
 
-      unsigned Reg = getRegForValue(U->getOperand(0));
+      unsigned Reg = getRegForValue(Src);
       if (!Reg)
         return false;
       Addr.setOffsetReg(Reg);
       return true;
     }
     break;
+  }
   case Instruction::Mul: {
     if (Addr.getOffsetReg())
       break;
@@ -661,23 +667,24 @@ bool AArch64FastISel::computeAddress(con
     Addr.setShift(Val);
     Addr.setExtendType(AArch64_AM::LSL);
 
-    if (const auto *I = dyn_cast<Instruction>(LHS))
+    const Value *Src = LHS;
+    if (const auto *I = dyn_cast<Instruction>(Src))
       if (FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB)
-        U = I;
+        Src = I;
 
-    if (const auto *ZE = dyn_cast<ZExtInst>(U))
+    if (const auto *ZE = dyn_cast<ZExtInst>(Src)) {
       if (ZE->getOperand(0)->getType()->isIntegerTy(32)) {
         Addr.setExtendType(AArch64_AM::UXTW);
-        LHS = U->getOperand(0);
+        Src = ZE->getOperand(0);
       }
-
-    if (const auto *SE = dyn_cast<SExtInst>(U))
+    } else if (const auto *SE = dyn_cast<SExtInst>(Src)) {
       if (SE->getOperand(0)->getType()->isIntegerTy(32)) {
         Addr.setExtendType(AArch64_AM::SXTW);
-        LHS = U->getOperand(0);
+        Src = SE->getOperand(0);
       }
+    }
 
-    unsigned Reg = getRegForValue(LHS);
+    unsigned Reg = getRegForValue(Src);
     if (!Reg)
       return false;
     Addr.setOffsetReg(Reg);
@@ -697,7 +704,7 @@ bool AArch64FastISel::computeAddress(con
       if (C->getValue() == 0xffffffff)
         std::swap(LHS, RHS);
 
-    if (const auto *C = cast<ConstantInt>(RHS))
+    if (const auto *C = dyn_cast<ConstantInt>(RHS))
       if (C->getValue() == 0xffffffff) {
         Addr.setShift(0);
         Addr.setExtendType(AArch64_AM::LSL);

Modified: llvm/trunk/test/CodeGen/AArch64/fast-isel-addressing-modes.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/fast-isel-addressing-modes.ll?rev=218161&r1=218160&r2=218161&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/fast-isel-addressing-modes.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/fast-isel-addressing-modes.ll Fri Sep 19 17:23:46 2014
@@ -450,6 +450,30 @@ define i64 @load_breg_and_offreg_4(i64 %
   ret i64 %5
 }
 
+; Not all 'and' instructions have immediates.
+define i64 @load_breg_and_offreg_5(i64 %a, i64 %b, i64 %c) {
+; CHECK-LABEL: load_breg_and_offreg_5
+; CHECK:       and [[REG:x[0-9]+]], x0, x2
+; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}[[REG]], x1{{\]}}
+  %1 = and i64 %a, %c
+  %2 = add i64 %1, %b
+  %3 = inttoptr i64 %2 to i64*
+  %4 = load i64* %3
+  ret i64 %4
+}
+
+define i64 @load_breg_and_offreg_6(i64 %a, i64 %b, i64 %c) {
+; CHECK-LABEL: load_breg_and_offreg_6
+; CHECK:       and [[REG:x[0-9]+]], x0, x2
+; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}x1, [[REG]], lsl #3{{\]}}
+  %1 = and i64 %a, %c
+  %2 = shl i64 %1, 3
+  %3 = add i64 %2, %b
+  %4 = inttoptr i64 %3 to i64*
+  %5 = load i64* %4
+  ret i64 %5
+}
+
 ; Load Base Register + Scaled Register Offset + Sign/Zero extension
 define i32 @load_breg_zext_shift_offreg_1(i32 %a, i64 %b) {
 ; CHECK-LABEL: load_breg_zext_shift_offreg_1
@@ -506,6 +530,21 @@ define i32 @load_breg_sext_shift_offreg_
   ret i32 %5
 }
 
+; Make sure that we don't drop the first 'add' instruction.
+define i32 @load_breg_sext_shift_offreg_3(i32 %a, i64 %b) {
+; CHECK-LABEL: load_breg_sext_shift_offreg_3
+; CHECK:       add [[REG:w[0-9]+]], w0, #4
+; CHECK:       ldr {{w[0-9]+}}, {{\[}}x1, [[REG]], sxtw #2{{\]}}
+  %1 = add i32 %a, 4
+  %2 = sext i32 %1 to i64
+  %3 = shl i64 %2, 2
+  %4 = add i64 %b, %3
+  %5 = inttoptr i64 %4 to i32*
+  %6 = load i32* %5
+  ret i32 %6
+}
+
+
 define i32 @load_breg_sext_mul_offreg_1(i32 %a, i64 %b) {
 ; CHECK-LABEL: load_breg_sext_mul_offreg_1
 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, sxtw #2]





More information about the llvm-commits mailing list