diff --git a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp --- a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp @@ -291,18 +291,15 @@ if (hasFP(MF)) { // Realign stack. if (RI->hasStackRealignment(MF)) { - unsigned ShiftAmount = Log2(MFI.getMaxAlign()); - Register VR = - MF.getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass); + unsigned MSB = Log2(MFI.getMaxAlign()); + assert(MSB > 0 && "The stack realignment size is invalid!"); BuildMI(MBB, MBBI, DL, - TII->get(IsLA64 ? LoongArch::SRLI_D : LoongArch::SRLI_W), VR) + TII->get(IsLA64 ? LoongArch::BSTRINS_D : LoongArch::BSTRINS_W), + SPReg) .addReg(SPReg) - .addImm(ShiftAmount) - .setMIFlag(MachineInstr::FrameSetup); - BuildMI(MBB, MBBI, DL, - TII->get(IsLA64 ? LoongArch::SLLI_D : LoongArch::SLLI_W), SPReg) - .addReg(VR) - .addImm(ShiftAmount) + .addReg(LoongArch::R0) + .addImm(MSB - 1) + .addImm(0) .setMIFlag(MachineInstr::FrameSetup); // FP will be used to restore the frame in the epilogue, so we need // another base register BP to record SP after re-alignment. SP will diff --git a/llvm/test/CodeGen/LoongArch/stack-realignment-with-variable-sized-objects.ll b/llvm/test/CodeGen/LoongArch/stack-realignment-with-variable-sized-objects.ll --- a/llvm/test/CodeGen/LoongArch/stack-realignment-with-variable-sized-objects.ll +++ b/llvm/test/CodeGen/LoongArch/stack-realignment-with-variable-sized-objects.ll @@ -19,8 +19,7 @@ ; LA32-NEXT: .cfi_offset 31, -12 ; LA32-NEXT: addi.w $fp, $sp, 64 ; LA32-NEXT: .cfi_def_cfa 22, 0 -; LA32-NEXT: srli.w $a1, $sp, 6 -; LA32-NEXT: slli.w $sp, $a1, 6 +; LA32-NEXT: bstrins.w $sp, $zero, 5, 0 ; LA32-NEXT: move $s8, $sp ; LA32-NEXT: addi.w $a0, $a0, 15 ; LA32-NEXT: addi.w $a1, $zero, -16 @@ -48,8 +47,7 @@ ; LA64-NEXT: .cfi_offset 31, -24 ; LA64-NEXT: addi.d $fp, $sp, 64 ; LA64-NEXT: .cfi_def_cfa 22, 0 -; LA64-NEXT: srli.d $a1, $sp, 6 -; LA64-NEXT: slli.d $sp, $a1, 6 +; LA64-NEXT: bstrins.d $sp, $zero, 5, 0 ; LA64-NEXT: move $s8, $sp ; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 ; LA64-NEXT: addi.d $a0, $a0, 15 diff --git a/llvm/test/CodeGen/LoongArch/stack-realignment.ll b/llvm/test/CodeGen/LoongArch/stack-realignment.ll --- a/llvm/test/CodeGen/LoongArch/stack-realignment.ll +++ b/llvm/test/CodeGen/LoongArch/stack-realignment.ll @@ -17,8 +17,7 @@ ; LA32-NEXT: .cfi_offset 22, -8 ; LA32-NEXT: addi.w $fp, $sp, 32 ; LA32-NEXT: .cfi_def_cfa 22, 0 -; LA32-NEXT: srli.w $a0, $sp, 5 -; LA32-NEXT: slli.w $sp, $a0, 5 +; LA32-NEXT: bstrins.w $sp, $zero, 4, 0 ; LA32-NEXT: addi.w $a0, $sp, 0 ; LA32-NEXT: bl %plt(callee) ; LA32-NEXT: addi.w $sp, $fp, -32 @@ -37,8 +36,7 @@ ; LA64-NEXT: .cfi_offset 22, -16 ; LA64-NEXT: addi.d $fp, $sp, 32 ; LA64-NEXT: .cfi_def_cfa 22, 0 -; LA64-NEXT: srli.d $a0, $sp, 5 -; LA64-NEXT: slli.d $sp, $a0, 5 +; LA64-NEXT: bstrins.d $sp, $zero, 4, 0 ; LA64-NEXT: addi.d $a0, $sp, 0 ; LA64-NEXT: bl %plt(callee) ; LA64-NEXT: addi.d $sp, $fp, -32 @@ -91,8 +89,7 @@ ; LA32-NEXT: .cfi_offset 22, -8 ; LA32-NEXT: addi.w $fp, $sp, 64 ; LA32-NEXT: .cfi_def_cfa 22, 0 -; LA32-NEXT: srli.w $a0, $sp, 6 -; LA32-NEXT: slli.w $sp, $a0, 6 +; LA32-NEXT: bstrins.w $sp, $zero, 5, 0 ; LA32-NEXT: addi.w $a0, $sp, 0 ; LA32-NEXT: bl %plt(callee) ; LA32-NEXT: addi.w $sp, $fp, -64 @@ -111,8 +108,7 @@ ; LA64-NEXT: .cfi_offset 22, -16 ; LA64-NEXT: addi.d $fp, $sp, 64 ; LA64-NEXT: .cfi_def_cfa 22, 0 -; LA64-NEXT: srli.d $a0, $sp, 6 -; LA64-NEXT: slli.d $sp, $a0, 6 +; LA64-NEXT: bstrins.d $sp, $zero, 5, 0 ; LA64-NEXT: addi.d $a0, $sp, 0 ; LA64-NEXT: bl %plt(callee) ; LA64-NEXT: addi.d $sp, $fp, -64 @@ -165,8 +161,7 @@ ; LA32-NEXT: .cfi_offset 22, -8 ; LA32-NEXT: addi.w $fp, $sp, 128 ; LA32-NEXT: .cfi_def_cfa 22, 0 -; LA32-NEXT: srli.w $a0, $sp, 7 -; LA32-NEXT: slli.w $sp, $a0, 7 +; LA32-NEXT: bstrins.w $sp, $zero, 6, 0 ; LA32-NEXT: addi.w $a0, $sp, 0 ; LA32-NEXT: bl %plt(callee) ; LA32-NEXT: addi.w $sp, $fp, -128 @@ -185,8 +180,7 @@ ; LA64-NEXT: .cfi_offset 22, -16 ; LA64-NEXT: addi.d $fp, $sp, 128 ; LA64-NEXT: .cfi_def_cfa 22, 0 -; LA64-NEXT: srli.d $a0, $sp, 7 -; LA64-NEXT: slli.d $sp, $a0, 7 +; LA64-NEXT: bstrins.d $sp, $zero, 6, 0 ; LA64-NEXT: addi.d $a0, $sp, 0 ; LA64-NEXT: bl %plt(callee) ; LA64-NEXT: addi.d $sp, $fp, -128 @@ -239,8 +233,7 @@ ; LA32-NEXT: .cfi_offset 22, -8 ; LA32-NEXT: addi.w $fp, $sp, 256 ; LA32-NEXT: .cfi_def_cfa 22, 0 -; LA32-NEXT: srli.w $a0, $sp, 8 -; LA32-NEXT: slli.w $sp, $a0, 8 +; LA32-NEXT: bstrins.w $sp, $zero, 7, 0 ; LA32-NEXT: addi.w $a0, $sp, 0 ; LA32-NEXT: bl %plt(callee) ; LA32-NEXT: addi.w $sp, $fp, -256 @@ -259,8 +252,7 @@ ; LA64-NEXT: .cfi_offset 22, -16 ; LA64-NEXT: addi.d $fp, $sp, 256 ; LA64-NEXT: .cfi_def_cfa 22, 0 -; LA64-NEXT: srli.d $a0, $sp, 8 -; LA64-NEXT: slli.d $sp, $a0, 8 +; LA64-NEXT: bstrins.d $sp, $zero, 7, 0 ; LA64-NEXT: addi.d $a0, $sp, 0 ; LA64-NEXT: bl %plt(callee) ; LA64-NEXT: addi.d $sp, $fp, -256 @@ -313,8 +305,7 @@ ; LA32-NEXT: .cfi_offset 22, -8 ; LA32-NEXT: addi.w $fp, $sp, 1024 ; LA32-NEXT: .cfi_def_cfa 22, 0 -; LA32-NEXT: srli.w $a0, $sp, 9 -; LA32-NEXT: slli.w $sp, $a0, 9 +; LA32-NEXT: bstrins.w $sp, $zero, 8, 0 ; LA32-NEXT: addi.w $a0, $sp, 512 ; LA32-NEXT: bl %plt(callee) ; LA32-NEXT: addi.w $sp, $fp, -1024 @@ -333,8 +324,7 @@ ; LA64-NEXT: .cfi_offset 22, -16 ; LA64-NEXT: addi.d $fp, $sp, 1024 ; LA64-NEXT: .cfi_def_cfa 22, 0 -; LA64-NEXT: srli.d $a0, $sp, 9 -; LA64-NEXT: slli.d $sp, $a0, 9 +; LA64-NEXT: bstrins.d $sp, $zero, 8, 0 ; LA64-NEXT: addi.d $a0, $sp, 512 ; LA64-NEXT: bl %plt(callee) ; LA64-NEXT: addi.d $sp, $fp, -1024 @@ -388,8 +378,7 @@ ; LA32-NEXT: addi.w $fp, $sp, 2032 ; LA32-NEXT: .cfi_def_cfa 22, 0 ; LA32-NEXT: addi.w $sp, $sp, -16 -; LA32-NEXT: srli.w $a0, $sp, 10 -; LA32-NEXT: slli.w $sp, $a0, 10 +; LA32-NEXT: bstrins.w $sp, $zero, 9, 0 ; LA32-NEXT: addi.w $a0, $sp, 1024 ; LA32-NEXT: bl %plt(callee) ; LA32-NEXT: addi.w $sp, $fp, -2048 @@ -410,8 +399,7 @@ ; LA64-NEXT: addi.d $fp, $sp, 2032 ; LA64-NEXT: .cfi_def_cfa 22, 0 ; LA64-NEXT: addi.d $sp, $sp, -16 -; LA64-NEXT: srli.d $a0, $sp, 10 -; LA64-NEXT: slli.d $sp, $a0, 10 +; LA64-NEXT: bstrins.d $sp, $zero, 9, 0 ; LA64-NEXT: addi.d $a0, $sp, 1024 ; LA64-NEXT: bl %plt(callee) ; LA64-NEXT: addi.d $sp, $fp, -2048 @@ -467,8 +455,7 @@ ; LA32-NEXT: .cfi_def_cfa 22, 0 ; LA32-NEXT: addi.w $sp, $sp, -2048 ; LA32-NEXT: addi.w $sp, $sp, -16 -; LA32-NEXT: srli.w $a0, $sp, 11 -; LA32-NEXT: slli.w $sp, $a0, 11 +; LA32-NEXT: bstrins.w $sp, $zero, 10, 0 ; LA32-NEXT: ori $a0, $zero, 2048 ; LA32-NEXT: add.w $a0, $sp, $a0 ; LA32-NEXT: bl %plt(callee) @@ -493,8 +480,7 @@ ; LA64-NEXT: .cfi_def_cfa 22, 0 ; LA64-NEXT: addi.d $sp, $sp, -2048 ; LA64-NEXT: addi.d $sp, $sp, -16 -; LA64-NEXT: srli.d $a0, $sp, 11 -; LA64-NEXT: slli.d $sp, $a0, 11 +; LA64-NEXT: bstrins.d $sp, $zero, 10, 0 ; LA64-NEXT: ori $a0, $zero, 2048 ; LA64-NEXT: add.d $a0, $sp, $a0 ; LA64-NEXT: bl %plt(callee) @@ -554,8 +540,7 @@ ; LA32-NEXT: lu12i.w $a0, 1 ; LA32-NEXT: ori $a0, $a0, 2064 ; LA32-NEXT: sub.w $sp, $sp, $a0 -; LA32-NEXT: srli.w $a0, $sp, 12 -; LA32-NEXT: slli.w $sp, $a0, 12 +; LA32-NEXT: bstrins.w $sp, $zero, 11, 0 ; LA32-NEXT: lu12i.w $a0, 1 ; LA32-NEXT: add.w $a0, $sp, $a0 ; LA32-NEXT: bl %plt(callee) @@ -582,8 +567,7 @@ ; LA64-NEXT: lu12i.w $a0, 1 ; LA64-NEXT: ori $a0, $a0, 2064 ; LA64-NEXT: sub.d $sp, $sp, $a0 -; LA64-NEXT: srli.d $a0, $sp, 12 -; LA64-NEXT: slli.d $sp, $a0, 12 +; LA64-NEXT: bstrins.d $sp, $zero, 11, 0 ; LA64-NEXT: lu12i.w $a0, 1 ; LA64-NEXT: add.d $a0, $sp, $a0 ; LA64-NEXT: bl %plt(callee)