Loading llvm/lib/Target/AArch64/AArch64FastISel.cpp +8 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading llvm/test/CodeGen/AArch64/arm64_32-fastisel.ll +21 −0 Original line number Diff line number Diff line Loading @@ -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 } llvm/test/CodeGen/AArch64/arm64_32.ll +23 −8 Original line number Diff line number Diff line Loading @@ -15,7 +15,9 @@ define i32* @test_global_addr() { ; CHECK-LABEL: test_global_addr: ; CHECK: adrp [[PAGE:x[0-9]+]], _var32@PAGE ; CHECK: add x0, [[PAGE]], _var32@PAGEOFF ; CHECK-OPT: add x0, [[PAGE]], _var32@PAGEOFF ; CHECK-FAST: add [[TMP:x[0-9]+]], [[PAGE]], _var32@PAGEOFF ; CHECK-FAST: and x0, [[TMP]], #0xffffffff ret i32* @var32 } Loading Loading @@ -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@GOTPAGE ; CHECK: ldr w0, [x[[PAGE]], _var_got@GOTPAGEOFF] ; CHECK-OPT: ldr w0, [x[[PAGE]], _var_got@GOTPAGEOFF] ; CHECK-FAST: ldr w[[TMP:[0-9]+]], [x[[PAGE]], _var_got@GOTPAGEOFF] ; CHECK-FAST: and x0, x[[TMP]], #0xffffffff ret i8* @var_got } Loading Loading @@ -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 } Loading @@ -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 } Loading @@ -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 } Loading Loading @@ -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() Loading Loading @@ -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 } Loading Loading
llvm/lib/Target/AArch64/AArch64FastISel.cpp +8 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading
llvm/test/CodeGen/AArch64/arm64_32-fastisel.ll +21 −0 Original line number Diff line number Diff line Loading @@ -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 }
llvm/test/CodeGen/AArch64/arm64_32.ll +23 −8 Original line number Diff line number Diff line Loading @@ -15,7 +15,9 @@ define i32* @test_global_addr() { ; CHECK-LABEL: test_global_addr: ; CHECK: adrp [[PAGE:x[0-9]+]], _var32@PAGE ; CHECK: add x0, [[PAGE]], _var32@PAGEOFF ; CHECK-OPT: add x0, [[PAGE]], _var32@PAGEOFF ; CHECK-FAST: add [[TMP:x[0-9]+]], [[PAGE]], _var32@PAGEOFF ; CHECK-FAST: and x0, [[TMP]], #0xffffffff ret i32* @var32 } Loading Loading @@ -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@GOTPAGE ; CHECK: ldr w0, [x[[PAGE]], _var_got@GOTPAGEOFF] ; CHECK-OPT: ldr w0, [x[[PAGE]], _var_got@GOTPAGEOFF] ; CHECK-FAST: ldr w[[TMP:[0-9]+]], [x[[PAGE]], _var_got@GOTPAGEOFF] ; CHECK-FAST: and x0, x[[TMP]], #0xffffffff ret i8* @var_got } Loading Loading @@ -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 } Loading @@ -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 } Loading @@ -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 } Loading Loading @@ -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() Loading Loading @@ -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 } Loading