[llvm] d6c0ef7 - [PowerPC] Handle base load with reservation mnemonic

Nemanja Ivanovic via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 3 07:13:18 PST 2021


Author: Nemanja Ivanovic
Date: 2021-12-03T09:13:02-06:00
New Revision: d6c0ef78876dc3204b0a6d92119b15aa9cd12af3

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

LOG: [PowerPC] Handle base load with reservation mnemonic

The Power ISA defined l[bhwdq]arx as both base and
extended mnemonics. The base mnemonic takes the EH
bit as an operand and the extended mnemonic omits
it, making it implicitly zero. The existing
implementation only handles the base mnemonic when
EH is 1 and internally produces a different
instruction. There are historical reasons for this.
This patch simply removes the limitation introduced
by this implementation that disallows the base
mnemonic with EH = 0 in the ASM parser.

This resolves an issue that prevented some files
in the Linux kernel from being built with
-fintegrated-as.

Also fix a crash if the value is not an integer immediate.

Added: 
    

Modified: 
    llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
    llvm/test/CodeGen/PowerPC/inline-asm-label.ll
    llvm/test/MC/PowerPC/ppc64-encoding-bookII.s
    llvm/test/MC/PowerPC/ppc64-errors.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index 9e181d4052d6f..ded922329ebf6 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -1576,6 +1576,16 @@ bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
     std::swap(Operands[2], Operands[1]);
   }
 
+  // Handle base mnemonic for atomic loads where the EH bit is zero.
+  if (Name == "lqarx" || Name == "ldarx" || Name == "lwarx" ||
+      Name == "lharx" || Name == "lbarx") {
+    if (Operands.size() != 5)
+      return false;
+    PPCOperand &EHOp = (PPCOperand &)*Operands[4];
+    if (EHOp.isU1Imm() && EHOp.getImm() == 0)
+      Operands.pop_back();
+  }
+
   return false;
 }
 
@@ -1745,7 +1755,7 @@ unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
   }
 
   PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);
-  if (Op.isImm() && Op.getImm() == ImmVal)
+  if (Op.isU3Imm() && Op.getImm() == ImmVal)
     return Match_Success;
 
   return Match_InvalidOperand;

diff  --git a/llvm/test/CodeGen/PowerPC/inline-asm-label.ll b/llvm/test/CodeGen/PowerPC/inline-asm-label.ll
index 6bacbd77aba2c..33d0fdc926d29 100644
--- a/llvm/test/CodeGen/PowerPC/inline-asm-label.ll
+++ b/llvm/test/CodeGen/PowerPC/inline-asm-label.ll
@@ -45,3 +45,39 @@ entry:
   ret i32 %4
 }
 
+define dso_local signext i32 @NoBarrier_CompareAndSwapExtMne(i32* %ptr, i32 signext %old_value, i32 signext %new_value) #0 {
+; CHECK-LABEL: NoBarrier_CompareAndSwapExtMne:
+; CHECK:    #APP
+; CHECK-NEXT:  L..tmp2:
+; CHECK-NEXT:    lwarx 6, 0, 3
+; CHECK-NEXT:    cmpw 4, 6
+; CHECK-NEXT:    bne- 0, L..tmp3
+; CHECK-NEXT:    stwcx. 5, 0, 3
+; CHECK-NEXT:    bne- 0, L..tmp2
+; CHECK-NEXT:  L..tmp3:
+
+; NOIS-LABEL: NoBarrier_CompareAndSwapExtMne:
+; NOIS:    #APP
+; NOIS-NEXT: 1: lwarx 6, 0, 3
+; NOIS-NEXT:    cmpw 4, 6
+; NOIS-NEXT:    bne- 2f
+; NOIS-NEXT:    stwcx. 5, 0, 3
+; NOIS-NEXT:    bne- 1b
+; NOIS-NEXT: 2:
+
+entry:
+  %ptr.addr = alloca i32*, align 8                                                                                                                                            %old_value.addr = alloca i32, align 4
+  %new_value.addr = alloca i32, align 4
+  %result = alloca i32, align 4
+  store i32* %ptr, i32** %ptr.addr, align 8
+  store i32 %old_value, i32* %old_value.addr, align 4
+  store i32 %new_value, i32* %new_value.addr, align 4
+  %0 = load i32*, i32** %ptr.addr, align 8
+  %1 = load i32, i32* %old_value.addr, align 4
+  %2 = load i32, i32* %new_value.addr, align 4
+  %3 = call i32 asm sideeffect "1:     lwarx $0, $4, $1, 0   \0A\09       cmpw $2, $0             \0A\09       bne- 2f                         \0A\09       stwcx. $3, $4, $1  \0A\09       bne- 1b                         \0A\092:                                     \0A\09", "=&b,b,b,b,i,~{cr0},~{ctr}"(i32* %0, i32 %1, i32 %2, i32 0)
+  store i32 %3, i32* %result, align 4
+  %4 = load i32, i32* %result, align 4
+  ret i32 %4
+}
+

diff  --git a/llvm/test/MC/PowerPC/ppc64-encoding-bookII.s b/llvm/test/MC/PowerPC/ppc64-encoding-bookII.s
index 447542fba672e..bd50e2321ffdf 100644
--- a/llvm/test/MC/PowerPC/ppc64-encoding-bookII.s
+++ b/llvm/test/MC/PowerPC/ppc64-encoding-bookII.s
@@ -130,18 +130,34 @@
 # CHECK-LE: lbarx 2, 3, 4                   # encoding: [0x68,0x20,0x43,0x7c]
             lbarx 2, 3, 4
 
+# CHECK-BE: lbarx 2, 3, 4                   # encoding: [0x7c,0x43,0x20,0x68]
+# CHECK-LE: lbarx 2, 3, 4                   # encoding: [0x68,0x20,0x43,0x7c]
+            lbarx 2, 3, 4, 0
+
 # CHECK-BE: lharx 2, 3, 4                   # encoding: [0x7c,0x43,0x20,0xe8]
 # CHECK-LE: lharx 2, 3, 4                   # encoding: [0xe8,0x20,0x43,0x7c]
             lharx 2, 3, 4
 
+# CHECK-BE: lharx 2, 3, 4                   # encoding: [0x7c,0x43,0x20,0xe8]
+# CHECK-LE: lharx 2, 3, 4                   # encoding: [0xe8,0x20,0x43,0x7c]
+            lharx 2, 3, 4, 0
+
 # CHECK-BE: lwarx 2, 3, 4                   # encoding: [0x7c,0x43,0x20,0x28]
 # CHECK-LE: lwarx 2, 3, 4                   # encoding: [0x28,0x20,0x43,0x7c]
             lwarx 2, 3, 4
 
+# CHECK-BE: lwarx 2, 3, 4                   # encoding: [0x7c,0x43,0x20,0x28]
+# CHECK-LE: lwarx 2, 3, 4                   # encoding: [0x28,0x20,0x43,0x7c]
+            lwarx 2, 3, 4, 0
+
 # CHECK-BE: ldarx 2, 3, 4                   # encoding: [0x7c,0x43,0x20,0xa8]
 # CHECK-LE: ldarx 2, 3, 4                   # encoding: [0xa8,0x20,0x43,0x7c]
             ldarx 2, 3, 4
 
+# CHECK-BE: ldarx 2, 3, 4                   # encoding: [0x7c,0x43,0x20,0xa8]
+# CHECK-LE: ldarx 2, 3, 4                   # encoding: [0xa8,0x20,0x43,0x7c]
+            ldarx 2, 3, 4, 0
+
 # CHECK-BE: lqarx 2, 3, 4                   # encoding: [0x7c,0x43,0x22,0x28]
 # CHECK-LE: lqarx 2, 3, 4                   # encoding: [0x28,0x22,0x43,0x7c]
             lqarx 2, 3, 4

diff  --git a/llvm/test/MC/PowerPC/ppc64-errors.s b/llvm/test/MC/PowerPC/ppc64-errors.s
index 6da7406e28280..627ae410db882 100644
--- a/llvm/test/MC/PowerPC/ppc64-errors.s
+++ b/llvm/test/MC/PowerPC/ppc64-errors.s
@@ -139,3 +139,7 @@
 # CHECK: error: invalid modifier 'got' (no symbols present)
          addi 4, 3, 123 at got
 # CHECK-NEXT: addi 4, 3, 123 at got
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: lwarx 1, 2, 3, a
+              lwarx 1, 2, 3, a


        


More information about the llvm-commits mailing list