Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions clang/test/CodeGen/PowerPC/inline-asm-constraints.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// RUN: %clang_cc1 -emit-llvm -triple powerpc64-ibm-aix-xcoff \
// RUN: %s -o - | FileCheck %s

#include <stdint.h>

// Test Atomic Memory Operation Support:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think these 2 lines are needed.

// This test case takes an address and performs an atomic load at that address.
// The purpose is to test the Q machine constraint and P machine constraint
// argument modifier together.
// These constraints on the pointer `ptr` read as: constrain (uint32_t*)ptr to
// read and writeable X-Form Addressed Memory operands.
static __attribute__((noinline))
uint32_t atomic_load(uint32_t *ptr, uint32_t val)
{
// CHECK-LABEL: define{{.*}} i32 @atomic_load(ptr noundef %ptr, i32 noundef zeroext %val)
// CHECK: %3 = call { i128, i32 } asm sideeffect "mr ${1:L},$3\0A\09 lwat $1,${0:P},$4\0A\09 mr $2,$1\0A", "=*Q,=&r,=r,r,n,0"(ptr elementtype(i32) %arrayidx, i32 %2, i32 0, i32 %1)
unsigned __int128 tmp;
uint32_t ret;
__asm__ volatile ("mr %L1,%3\n"
"\t lwat %1,%P0,%4\n"
"\t mr %2,%1\n"
: "+Q" (ptr[0]), "=&r" (tmp), "=r" (ret)
: "r" (val), "n" (0x00));
return ret;
}

int main(int argc, char **argv) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given what the checks are, main seems not needed.

return atomic_load((uint32_t*)argv[1], (uint32_t)*(argv[2]));
}
22 changes: 20 additions & 2 deletions llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,11 +411,26 @@ bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
const char *ExtraCode,
raw_ostream &O) {
auto reportAsmMemError = [&](StringRef errMsg) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ErrMsg?

const char *AsmStr = MI->getOperand(0).getSymbolName();
const MDNode *LocMD = MI->getLocCookieMD();
uint64_t LocCookie =
LocMD ? mdconst::extract<ConstantInt>(LocMD->getOperand(0))
->getZExtValue()
: 0;
const Function &Fn = MI->getMF()->getFunction();
Fn.getContext().diagnose(
DiagnosticInfoInlineAsm(LocCookie, errMsg + Twine(AsmStr) + "'"));
return true;
};
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
if (ExtraCode[1] != 0)
return reportAsmMemError("Unknown modifier in inline asm:");

switch (ExtraCode[0]) {
default: return true; // Unknown modifier.
default: {
return reportAsmMemError("Unknown modifier in inline asm:");
}
case 'L': // A memory reference to the upper word of a double word op.
O << getDataLayout().getPointerSize() << "(";
printOperand(MI, OpNo, O);
Expand All @@ -425,6 +440,9 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
O << "0, ";
printOperand(MI, OpNo, O);
return false;
case 'P': // A memory reference for an single inout to an X-form instr.
printOperand(MI, OpNo, O);
return false;
case 'I':
// Write 'i' if an integer constant, otherwise nothing. Used to print
// addi vs add, etc.
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/PowerPC/PPCISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17882,6 +17882,7 @@ PPCTargetLowering::getConstraintType(StringRef Constraint) const {
case 'y':
return C_RegisterClass;
case 'Z':
case 'Q':
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe put the 'Q' above the 'Z' so the comment is adjacent.

// FIXME: While Z does indicate a memory constraint, it specifically
// indicates an r+r address (used in conjunction with the 'y' modifier
// in the replacement string). Currently, we're forcing the base
Expand Down
21 changes: 21 additions & 0 deletions llvm/test/CodeGen/PowerPC/inline-asm-constraints.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -verify-machineinstrs < %s -mcpu=pwr8 \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lwat is a pwr9 instruction. I guess the cpu isn't checked for inline asm? But if we're going to specify a cpu it should probably be pwr9.

; RUN: -mtriple=powerpc64-ibm-aix-xcoff | FileCheck %s

define zeroext i32 @atomic_load(ptr %ptr, i32 zeroext range(i32 0, 256) %val) {
; CHECK-LABEL: atomic_load:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: #APP
; CHECK-NEXT: mr 6, 4
; CHECK-NEXT: lwat 5, 3, 0
; CHECK-NEXT: mr 3, 5
; CHECK-EMPTY:
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: clrldi 3, 3, 32
; CHECK-NEXT: blr
entry:
%0 = load i32, ptr %ptr, align 4
%1 = tail call { i128, i32 } asm sideeffect "mr ${1:L},$3\0A\09 lwat $1,${0:P},$4\0A\09 mr $2,$1\0A", "=*Q,=&r,=r,r,n,0"(ptr nonnull elementtype(i32) %ptr, i32 %val, i32 0, i32 %0)
%asmresult1 = extractvalue { i128, i32 } %1, 1
ret i32 %asmresult1
}
Loading