From ae38254eeaf53b95f347c3657f61c271051bd978 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Tue, 8 Oct 2024 13:52:15 -0400 Subject: [PATCH 1/3] [PowerPC] Expand global named register support Enable all valid registers for intrinsics that read from and write to global named registers. --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 30 +++++++++++-------- .../CodeGen/PowerPC/named-reg-alloc-r0.ll | 9 +++--- .../CodeGen/PowerPC/named-reg-alloc-r2-64.ll | 3 +- .../CodeGen/PowerPC/named-reg-alloc-r2.ll | 3 +- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 7199fac9b110b..7e3c9df1d8d8e 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -17367,25 +17367,29 @@ SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op, return FrameAddr; } -// FIXME? Maybe this could be a TableGen attribute on some registers and -// this table could be generated automatically from RegInfo. +#define GET_REGISTER_MATCHER +#include "PPCGenAsmMatcher.inc" + Register PPCTargetLowering::getRegisterByName(const char* RegName, LLT VT, const MachineFunction &MF) const { - bool isPPC64 = Subtarget.isPPC64(); - bool is64Bit = isPPC64 && VT == LLT::scalar(64); - if (!is64Bit && VT != LLT::scalar(32)) + bool Is64Bit = Subtarget.isPPC64() && VT == LLT::scalar(64); + if (!Is64Bit && VT != LLT::scalar(32)) report_fatal_error("Invalid register global variable type"); - Register Reg = StringSwitch(RegName) - .Case("r1", is64Bit ? PPC::X1 : PPC::R1) - .Case("r2", isPPC64 ? Register() : PPC::R2) - .Case("r13", (is64Bit ? PPC::X13 : PPC::R13)) - .Default(Register()); + Register Reg = MatchRegisterName(RegName); + if (!Reg) + report_fatal_error(Twine("Invalid global name register \"" + + StringRef(RegName) + "\".")); + + // Convert GPR to GP8R register for 64bit. + if (Is64Bit && StringRef(RegName).starts_with_insensitive("r")) + Reg = Reg.id() - PPC::R0 + PPC::X0; - if (Reg) - return Reg; - report_fatal_error("Invalid register name global variable"); + if (Subtarget.getRegisterInfo()->getReservedRegs(MF).test(Reg)) + report_fatal_error(Twine("Trying to obtain non-reservable register \"" + + StringRef(RegName) + "\".")); + return Reg; } bool PPCTargetLowering::isAccessedAsGotIndirect(SDValue GA) const { diff --git a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r0.ll b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r0.ll index 11cb72296e2c4..be2fae8f3458b 100644 --- a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r0.ll +++ b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r0.ll @@ -1,11 +1,10 @@ -; RUN: not --crash llc < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s -; RUN: not --crash llc < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s -; RUN: not --crash llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: not --crash llc -O0 < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: not --crash llc -O0 < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: not --crash llc -O0 < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s define i32 @get_reg() nounwind { entry: -; FIXME: Include an allocatable-specific error message -; CHECK: Invalid register name global variable +; CHECK: Trying to obtain non-reservable register "r0". %reg = call i32 @llvm.read_register.i32(metadata !0) ret i32 %reg } diff --git a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll index 3df778f445c73..b245c7d6f76c1 100644 --- a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll +++ b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll @@ -3,8 +3,7 @@ define i64 @get_reg() nounwind { entry: -; FIXME: Include an allocatable-specific error message -; CHECK: Invalid register name global variable +; CHECK: Trying to obtain non-reservable register "r2". %reg = call i64 @llvm.read_register.i64(metadata !0) ret i64 %reg } diff --git a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2.ll b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2.ll index ca79f857548eb..ac79aa381ea7e 100644 --- a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2.ll +++ b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2.ll @@ -3,8 +3,7 @@ define i32 @get_reg() nounwind { entry: -; FIXME: Include an allocatable-specific error message -; CHECK-NOTPPC32: Invalid register name global variable +; CHECK-NOTPPC32: Trying to obtain non-reservable register "r2". %reg = call i32 @llvm.read_register.i32(metadata !0) ret i32 %reg From 87a59ce91a81b7d588e4fcec6ff63e03fbed6d0c Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Wed, 16 Oct 2024 15:43:31 -0400 Subject: [PATCH 2/3] Do not allow usage of reserved registers --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 7e3c9df1d8d8e..0f935d2d94b61 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -17370,7 +17370,7 @@ SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op, #define GET_REGISTER_MATCHER #include "PPCGenAsmMatcher.inc" -Register PPCTargetLowering::getRegisterByName(const char* RegName, LLT VT, +Register PPCTargetLowering::getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const { bool Is64Bit = Subtarget.isPPC64() && VT == LLT::scalar(64); @@ -17379,15 +17379,15 @@ Register PPCTargetLowering::getRegisterByName(const char* RegName, LLT VT, Register Reg = MatchRegisterName(RegName); if (!Reg) - report_fatal_error(Twine("Invalid global name register \"" - + StringRef(RegName) + "\".")); + report_fatal_error( + Twine("Invalid global name register \"" + StringRef(RegName) + "\".")); // Convert GPR to GP8R register for 64bit. if (Is64Bit && StringRef(RegName).starts_with_insensitive("r")) Reg = Reg.id() - PPC::R0 + PPC::X0; if (Subtarget.getRegisterInfo()->getReservedRegs(MF).test(Reg)) - report_fatal_error(Twine("Trying to obtain non-reservable register \"" + + report_fatal_error(Twine("Trying to obtain a reserved register \"" + StringRef(RegName) + "\".")); return Reg; } From 78536f120010cbfb7c19dad01211a004e84d11a0 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Fri, 18 Oct 2024 11:47:31 -0400 Subject: [PATCH 3/3] fix conditions and add tc to utilitze new supported registers --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 9 +- .../CodeGen/PowerPC/named-reg-alloc-r0.ll | 3 +- .../CodeGen/PowerPC/named-reg-alloc-r1-64.ll | 6 +- .../CodeGen/PowerPC/named-reg-alloc-r1.ll | 9 +- .../CodeGen/PowerPC/named-reg-alloc-r13-64.ll | 7 +- .../CodeGen/PowerPC/named-reg-alloc-r13.ll | 8 +- .../CodeGen/PowerPC/named-reg-alloc-r2-64.ll | 3 +- .../CodeGen/PowerPC/named-reg-alloc-r2.ll | 8 +- llvm/test/CodeGen/PowerPC/named-reg-alloc.ll | 144 ++++++++++++++++++ 9 files changed, 167 insertions(+), 30 deletions(-) create mode 100644 llvm/test/CodeGen/PowerPC/named-reg-alloc.ll diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 0f935d2d94b61..a4f0444ff2a64 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -17372,8 +17372,9 @@ SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op, Register PPCTargetLowering::getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const { + bool IsPPC64 = Subtarget.isPPC64(); - bool Is64Bit = Subtarget.isPPC64() && VT == LLT::scalar(64); + bool Is64Bit = IsPPC64 && VT == LLT::scalar(64); if (!Is64Bit && VT != LLT::scalar(32)) report_fatal_error("Invalid register global variable type"); @@ -17382,6 +17383,12 @@ Register PPCTargetLowering::getRegisterByName(const char *RegName, LLT VT, report_fatal_error( Twine("Invalid global name register \"" + StringRef(RegName) + "\".")); + // FIXME: These registers are not flagged as reserved and we can generate + // code for `-O0` but not for `-O2`. Need followup investigation as to why. + if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0) + report_fatal_error(Twine("Trying to reserve an invalid register \"" + + StringRef(RegName) + "\".")); + // Convert GPR to GP8R register for 64bit. if (Is64Bit && StringRef(RegName).starts_with_insensitive("r")) Reg = Reg.id() - PPC::R0 + PPC::X0; diff --git a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r0.ll b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r0.ll index be2fae8f3458b..c6b9498a680f4 100644 --- a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r0.ll +++ b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r0.ll @@ -1,10 +1,9 @@ ; RUN: not --crash llc -O0 < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s -; RUN: not --crash llc -O0 < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s ; RUN: not --crash llc -O0 < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s define i32 @get_reg() nounwind { entry: -; CHECK: Trying to obtain non-reservable register "r0". +; CHECK: Trying to reserve an invalid register "r0". %reg = call i32 @llvm.read_register.i32(metadata !0) ret i32 %reg } diff --git a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r1-64.ll b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r1-64.ll index 080b1982c88cb..96dbddd5bf157 100644 --- a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r1-64.ll +++ b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r1-64.ll @@ -1,12 +1,10 @@ -; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: not --crash llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s define i64 @get_reg() nounwind { +; CHECK: Trying to obtain a reserved register "r1". entry: %reg = call i64 @llvm.read_register.i64(metadata !0) ret i64 %reg - -; CHECK-LABEL: get_reg -; CHECK: mr 3, 1 } declare i64 @llvm.read_register.i64(metadata) nounwind diff --git a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r1.ll b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r1.ll index 6edd787e445e4..5980d09bc9c90 100644 --- a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r1.ll +++ b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r1.ll @@ -1,14 +1,11 @@ -; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s -; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: not --crash llc < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: not --crash llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s define i32 @get_reg() nounwind { +; CHECK: Trying to obtain a reserved register "r1". entry: %reg = call i32 @llvm.read_register.i32(metadata !0) ret i32 %reg - -; CHECK-LABEL: @get_reg -; CHECK: mr 3, 1 - } declare i32 @llvm.read_register.i32(metadata) nounwind diff --git a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r13-64.ll b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r13-64.ll index 4d73fb3e81869..8bd4d899f7260 100644 --- a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r13-64.ll +++ b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r13-64.ll @@ -1,13 +1,10 @@ -; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: not --crash llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s define i64 @get_reg() nounwind { +; CHECK: Trying to obtain a reserved register "r13". entry: %reg = call i64 @llvm.read_register.i64(metadata !0) ret i64 %reg - -; CHECK-LABEL: @get_reg -; CHECK: mr 3, 13 - } declare i64 @llvm.read_register.i64(metadata) nounwind diff --git a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r13.ll b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r13.ll index a7b778147980a..2185a8a6cd537 100644 --- a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r13.ll +++ b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r13.ll @@ -1,13 +1,11 @@ -; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s -; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: not --crash llc < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: not --crash llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s define i32 @get_reg() nounwind { +; CHECK: Trying to obtain a reserved register "r13". entry: %reg = call i32 @llvm.read_register.i32(metadata !0) ret i32 %reg - -; CHECK-LABEL: @get_reg -; CHECK: mr 3, 13 } declare i32 @llvm.read_register.i32(metadata) nounwind diff --git a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll index b245c7d6f76c1..fdf7ea2711d82 100644 --- a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll +++ b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2-64.ll @@ -1,9 +1,8 @@ ; RUN: not --crash llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s -; RUN: not --crash llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s define i64 @get_reg() nounwind { entry: -; CHECK: Trying to obtain non-reservable register "r2". +; CHECK: Trying to reserve an invalid register "r2". %reg = call i64 @llvm.read_register.i64(metadata !0) ret i64 %reg } diff --git a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2.ll b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2.ll index ac79aa381ea7e..58c782901f3eb 100644 --- a/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2.ll +++ b/llvm/test/CodeGen/PowerPC/named-reg-alloc-r2.ll @@ -1,14 +1,12 @@ -; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: not --crash llc < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s ; RUN: not --crash llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s --check-prefix=CHECK-NOTPPC32 define i32 @get_reg() nounwind { entry: -; CHECK-NOTPPC32: Trying to obtain non-reservable register "r2". +; CHECK-NOTPPC32: Trying to reserve an invalid register "r2". +; CHECK: Trying to obtain a reserved register "r2". %reg = call i32 @llvm.read_register.i32(metadata !0) ret i32 %reg - -; CHECK-LABEL: @get_reg -; CHECK: mr 3, 2 } declare i32 @llvm.read_register.i32(metadata) nounwind diff --git a/llvm/test/CodeGen/PowerPC/named-reg-alloc.ll b/llvm/test/CodeGen/PowerPC/named-reg-alloc.ll new file mode 100644 index 0000000000000..38d22475ead91 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/named-reg-alloc.ll @@ -0,0 +1,144 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -O0 -verify-machineinstrs < %s -mtriple=powerpc-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: llc -O0 -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s --check-prefix=CHECK64 + +@mVal = dso_local global i32 15, align 4 +@myGVal = dso_local global i32 0, align 4 + +define dso_local void @testSetIntReg(i32 noundef signext %xx) { +; CHECK-LABEL: testSetIntReg: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mr 5, 3 +; CHECK-NEXT: blr +; +; CHECK64-LABEL: testSetIntReg: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: mr 5, 3 +; CHECK64-NEXT: blr +entry: + tail call void @llvm.write_register.i32(metadata !0, i32 %xx) + ret void +} + +declare void @llvm.write_register.i32(metadata, i32) + +define dso_local signext range(i32 0, 2) i32 @testCmpReg() { +; CHECK-LABEL: testCmpReg: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lis 3, mVal@ha +; CHECK-NEXT: lwz 3, mVal@l(3) +; CHECK-NEXT: xori 3, 3, 15 +; CHECK-NEXT: cntlzw 3, 3 +; CHECK-NEXT: srwi 3, 3, 5 +; CHECK-NEXT: blr +; +; CHECK64-LABEL: testCmpReg: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: addis 3, 2, mVal@toc@ha +; CHECK64-NEXT: addi 3, 3, mVal@toc@l +; CHECK64-NEXT: lwz 3, 0(3) +; CHECK64-NEXT: xori 3, 3, 15 +; CHECK64-NEXT: cntlzw 3, 3 +; CHECK64-NEXT: srwi 3, 3, 5 +; CHECK64-NEXT: extsw 3, 3 +; CHECK64-NEXT: blr +entry: + tail call void @llvm.write_register.i32(metadata !0, i32 15) + %0 = load i32, ptr @mVal, align 4 + %1 = tail call i32 @llvm.read_register.i32(metadata !0) + %cmp = icmp eq i32 %0, %1 + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +declare i32 @llvm.read_register.i32(metadata) + +define dso_local void @testSetIntReg2(i32 noundef signext %xx) { +; CHECK-LABEL: testSetIntReg2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: stwu 1, -48(1) +; CHECK-NEXT: .cfi_def_cfa_offset 48 +; CHECK-NEXT: .cfi_offset r23, -36 +; CHECK-NEXT: stw 23, 12(1) # 4-byte Folded Spill +; CHECK-NEXT: mr 23, 3 +; CHECK-NEXT: lwz 23, 12(1) # 4-byte Folded Reload +; CHECK-NEXT: addi 1, 1, 48 +; CHECK-NEXT: blr +; +; CHECK64-LABEL: testSetIntReg2: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: std 23, -72(1) # 8-byte Folded Spill +; CHECK64-NEXT: mr 23, 3 +; CHECK64-NEXT: ld 23, -72(1) # 8-byte Folded Reload +; CHECK64-NEXT: blr +entry: + tail call void @llvm.write_register.i32(metadata !1, i32 %xx) + ret void +} + +define dso_local signext i32 @testReturnReg() { +; CHECK-LABEL: testReturnReg: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: stwu 1, -48(1) +; CHECK-NEXT: .cfi_def_cfa_offset 48 +; CHECK-NEXT: .cfi_offset r23, -36 +; CHECK-NEXT: stw 23, 12(1) # 4-byte Folded Spill +; CHECK-NEXT: li 23, 125 +; CHECK-NEXT: mr 3, 23 +; CHECK-NEXT: lwz 23, 12(1) # 4-byte Folded Reload +; CHECK-NEXT: addi 1, 1, 48 +; CHECK-NEXT: blr +; +; CHECK64-LABEL: testReturnReg: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: std 23, -72(1) # 8-byte Folded Spill +; CHECK64-NEXT: li 23, 125 +; CHECK64-NEXT: extsw 3, 23 +; CHECK64-NEXT: ld 23, -72(1) # 8-byte Folded Reload +; CHECK64-NEXT: blr +entry: + tail call void @llvm.write_register.i32(metadata !1, i32 125) + %0 = tail call i32 @llvm.read_register.i32(metadata !1) + ret i32 %0 +} + +define dso_local void @testViaASM(i32 noundef signext %xx) { +; CHECK-LABEL: testViaASM: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: stwu 1, -64(1) +; CHECK-NEXT: .cfi_def_cfa_offset 64 +; CHECK-NEXT: .cfi_offset r20, -48 +; CHECK-NEXT: stw 20, 16(1) # 4-byte Folded Spill +; CHECK-NEXT: mr 20, 3 +; CHECK-NEXT: #APP +; CHECK-NEXT: addi 3, 1, 1 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: lis 4, myGVal@ha +; CHECK-NEXT: stw 3, myGVal@l(4) +; CHECK-NEXT: lwz 20, 16(1) # 4-byte Folded Reload +; CHECK-NEXT: addi 1, 1, 64 +; CHECK-NEXT: blr +; +; CHECK64-LABEL: testViaASM: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: std 20, -96(1) # 8-byte Folded Spill +; CHECK64-NEXT: mr 20, 3 +; CHECK64-NEXT: #APP +; CHECK64-NEXT: addi 3, 1, 1 +; CHECK64-NEXT: #NO_APP +; CHECK64-NEXT: addis 4, 2, myGVal@toc@ha +; CHECK64-NEXT: addi 4, 4, myGVal@toc@l +; CHECK64-NEXT: stw 3, 0(4) +; CHECK64-NEXT: ld 20, -96(1) # 8-byte Folded Reload +; CHECK64-NEXT: blr +entry: + tail call void @llvm.write_register.i32(metadata !2, i32 %xx) + %0 = tail call i32 @llvm.read_register.i32(metadata !2) + %1 = tail call i32 asm "addi $0, $2, $2", "=r,{r20},K"(i32 %0, i32 1) + store i32 %1, ptr @myGVal, align 4 + ret void +} + +!0 = !{!"r5"} +!1 = !{!"r23"} +!2 = !{!"r20"}