[llvm] dea8f3b - arm64_32: support function return in FastISel.

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 18 06:35:22 PST 2019


Author: Tim Northover
Date: 2019-11-18T14:35:05Z
New Revision: dea8f3b0a4eabb930f605343ff5e3e39a1791f86

URL: https://github.com/llvm/llvm-project/commit/dea8f3b0a4eabb930f605343ff5e3e39a1791f86
DIFF: https://github.com/llvm/llvm-project/commit/dea8f3b0a4eabb930f605343ff5e3e39a1791f86.diff

LOG: arm64_32: support function return in FastISel.

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/AArch64FastISel.cpp
    llvm/test/CodeGen/AArch64/arm64_32-fastisel.ll
    llvm/test/CodeGen/AArch64/arm64_32.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
index 98410c2e747e..7a8243ad7c94 100644
--- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
@@ -3838,11 +3838,6 @@ bool AArch64FastISel::selectRet(const Instruction *I) {
   if (!FuncInfo.CanLowerReturn)
     return false;
 
-  // FIXME: in principle it could. Mostly just a case of zero extending outgoing
-  // pointers.
-  if (Subtarget->isTargetILP32())
-    return false;
-
   if (F.isVarArg())
     return false;
 
@@ -3922,6 +3917,11 @@ bool AArch64FastISel::selectRet(const Instruction *I) {
         return false;
     }
 
+    // "Callee" (i.e. value producer) zero extends pointers at function
+    // boundary.
+    if (Subtarget->isTargetILP32() && RV->getType()->isPointerTy())
+      SrcReg = emitAnd_ri(MVT::i64, SrcReg, false, 0xffffffff);
+
     // Make the copy.
     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
             TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);
@@ -5011,6 +5011,9 @@ std::pair<unsigned, bool> AArch64FastISel::getRegForGEPIndex(const Value *Idx) {
 /// simple cases. This is because the standard fastEmit functions don't cover
 /// MUL at all and ADD is lowered very inefficientily.
 bool AArch64FastISel::selectGetElementPtr(const Instruction *I) {
+  if (Subtarget->isTargetILP32())
+    return false;
+
   unsigned N = getRegForValue(I->getOperand(0));
   if (!N)
     return false;

diff  --git a/llvm/test/CodeGen/AArch64/arm64_32-fastisel.ll b/llvm/test/CodeGen/AArch64/arm64_32-fastisel.ll
index 15baad215a18..0467a2cba831 100644
--- a/llvm/test/CodeGen/AArch64/arm64_32-fastisel.ll
+++ b/llvm/test/CodeGen/AArch64/arm64_32-fastisel.ll
@@ -26,3 +26,24 @@ define void @test_struct_return(i32* %addr) {
   store i32 %res.1, i32* %addr
   ret void
 }
+
+define i8* @test_ret_ptr(i64 %in) {
+; CHECK-LABEL: test_ret_ptr:
+; CHECK: add [[TMP:x[0-9]]], x0, #1
+; CHECK: and x0, [[TMP]], #0xffffffff
+
+  %sum = add i64 %in, 1
+  %res = inttoptr i64 %sum to i8*
+  ret i8* %res
+}
+
+; Handled by SDAG because the struct confuses FastISel, which is fine.
+define {i8*} @test_ret_ptr_struct(i64 %in) {
+; CHECK-LABEL: test_ret_ptr_struct:
+; CHECK: add {{w[0-9]+}}, {{w[0-9]+}}, #1
+
+  %sum = add i64 %in, 1
+  %res.ptr = inttoptr i64 %sum to i8*
+  %res = insertvalue {i8*} undef, i8* %res.ptr, 0
+  ret {i8*} %res
+}

diff  --git a/llvm/test/CodeGen/AArch64/arm64_32.ll b/llvm/test/CodeGen/AArch64/arm64_32.ll
index 5fd619409a11..ee8f4cc82957 100644
--- a/llvm/test/CodeGen/AArch64/arm64_32.ll
+++ b/llvm/test/CodeGen/AArch64/arm64_32.ll
@@ -15,7 +15,9 @@
 define i32* @test_global_addr() {
 ; CHECK-LABEL: test_global_addr:
 ; CHECK: adrp [[PAGE:x[0-9]+]], _var32 at PAGE
-; CHECK: add x0, [[PAGE]], _var32 at PAGEOFF
+; CHECK-OPT: add x0, [[PAGE]], _var32 at PAGEOFF
+; CHECK-FAST: add [[TMP:x[0-9]+]], [[PAGE]], _var32 at PAGEOFF
+; CHECK-FAST: and x0, [[TMP]], #0xffffffff
   ret i32* @var32
 }
 
@@ -156,7 +158,9 @@ define i32 @test_unsafe_negative_unscaled_add() {
 define i8* @test_got_addr() {
 ; CHECK-LABEL: test_got_addr:
 ; CHECK: adrp x[[PAGE:[0-9]+]], _var_got at GOTPAGE
-; CHECK: ldr w0, [x[[PAGE]], _var_got at GOTPAGEOFF]
+; CHECK-OPT: ldr w0, [x[[PAGE]], _var_got at GOTPAGEOFF]
+; CHECK-FAST: ldr w[[TMP:[0-9]+]], [x[[PAGE]], _var_got at GOTPAGEOFF]
+; CHECK-FAST: and x0, x[[TMP]], #0xffffffff
   ret i8* @var_got
 }
 
@@ -229,7 +233,9 @@ declare i8* @llvm.frameaddress(i32)
 
 define i8* @test_frameaddr() {
 ; CHECK-LABEL: test_frameaddr:
-; CHECK: ldr {{w0|x0}}, [x29]
+; CHECK-OPT: ldr x0, [x29]
+; CHECK-FAST: ldr [[TMP:x[0-9]+]], [x29]
+; CHECK-FAST: and x0, [[TMP]], #0xffffffff
   %val = call i8* @llvm.frameaddress(i32 1)
   ret i8* %val
 }
@@ -238,7 +244,8 @@ declare i8* @llvm.returnaddress(i32)
 
 define i8* @test_toplevel_returnaddr() {
 ; CHECK-LABEL: test_toplevel_returnaddr:
-; CHECK: mov x0, x30
+; CHECK-OPT: mov x0, x30
+; CHECK-FAST: and x0, x30, #0xffffffff
   %val = call i8* @llvm.returnaddress(i32 0)
   ret i8* %val
 }
@@ -246,7 +253,9 @@ define i8* @test_toplevel_returnaddr() {
 define i8* @test_deep_returnaddr() {
 ; CHECK-LABEL: test_deep_returnaddr:
 ; CHECK: ldr x[[FRAME_REC:[0-9]+]], [x29]
-; CHECK: ldr x0, [x[[FRAME_REC]], #8]
+; CHECK-OPT: ldr x0, [x[[FRAME_REC]], #8]
+; CHECK-FAST: ldr [[TMP:x[0-9]+]], [x[[FRAME_REC]], #8]
+; CHECK-FAST: and x0, [[TMP]], #0xffffffff
   %val = call i8* @llvm.returnaddress(i32 1)
   ret i8* %val
 }
@@ -651,6 +660,7 @@ define void @test_struct_hi(i32 %hi) nounwind {
 ; CHECK-LABEL: test_struct_hi:
 ; CHECK: mov w[[IN:[0-9]+]], w0
 ; CHECK: bl _get_int
+; CHECK-FAST-NEXT: mov w0, w0
 ; CHECK-NEXT: bfi x0, x[[IN]], #32, #32
 ; CHECK-NEXT: bl _take_pair
   %val.64 = call i64 @get_int()
@@ -691,9 +701,14 @@ false:
 
 define { [18 x i8] }* @test_gep_nonpow2({ [18 x i8] }* %a0, i32 %a1) {
 ; CHECK-LABEL: test_gep_nonpow2:
-; CHECK:      mov w[[SIZE:[0-9]+]], #18
-; CHECK-NEXT: smaddl x0, w1, w[[SIZE]], x0
-; CHECK-NEXT: ret
+; CHECK-OPT:      mov w[[SIZE:[0-9]+]], #18
+; CHECK-OPT-NEXT: smaddl x0, w1, w[[SIZE]], x0
+; CHECK-OPT-NEXT: ret
+
+; CHECK-FAST:      mov w[[SIZE:[0-9]+]], #18
+; CHECK-FAST-NEXT: smaddl [[TMP:x[0-9]+]], w1, w[[SIZE]], x0
+; CHECK-FAST-NEXT: and x0, [[TMP]], #0xffffffff
+; CHECK-FAST-NEXT: ret
   %tmp0 = getelementptr inbounds { [18 x i8] }, { [18 x i8] }* %a0, i32 %a1
   ret { [18 x i8] }* %tmp0
 }


        


More information about the llvm-commits mailing list