From aede24ecaa08db806fb173faf2de9cff95df8cee Mon Sep 17 00:00:00 2001 From: Nemanja Ivanovic Date: Fri, 22 May 2020 07:59:12 -0500 Subject: [PATCH] [PowerPC] Treat 'Z' inline asm constraint as a true memory constraint We currently emit incorrect codegen for this constraint because we set it as a constraint that allows registers. This will cause the value to be copied to the stack and that address to be passed as the address. This is not what we want. Fixes: https://bugs.llvm.org/show_bug.cgi?id=42762 Differential revision: https://reviews.llvm.org/D77542 --- clang/lib/Basic/Targets/PPC.h | 3 ++- clang/test/CodeGen/ppc64-inline-asm.c | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 6261a49..7c19a96 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -276,11 +276,12 @@ public: break; case 'Q': // Memory operand that is an offset from a register (it is // usually better to use `m' or `es' in asm statements) + Info.setAllowsRegister(); + LLVM_FALLTHROUGH; case 'Z': // Memory operand that is an indexed or indirect from a // register (it is usually better to use `m' or `es' in // asm statements) Info.setAllowsMemory(); - Info.setAllowsRegister(); break; case 'R': // AIX TOC entry case 'a': // Address operand that is an indexed or indirect from a diff --git a/clang/test/CodeGen/ppc64-inline-asm.c b/clang/test/CodeGen/ppc64-inline-asm.c index 3e958c3..0b32d0b 100644 --- a/clang/test/CodeGen/ppc64-inline-asm.c +++ b/clang/test/CodeGen/ppc64-inline-asm.c @@ -37,3 +37,16 @@ double test_fmax(double x, double y) { // CHECK-LABEL: double @test_fmax(double %x, double %y) // CHECK: call double asm "xsmaxdp ${0:x}, ${1:x}, ${2:x}", "=^ws,^ws,^ws"(double %x, double %y) } + +void testZ(void *addr) { + asm volatile ("dcbz %y0\n" :: "Z"(*(unsigned char *)addr) : "memory"); +// CHECK-LABEL: void @testZ(i8* %addr) +// CHECK: call void asm sideeffect "dcbz ${0:y}\0A", "*Z,~{memory}"(i8* %addr) +} + +void testZwOff(void *addr, long long off) { + asm volatile ("dcbz %y0\n" :: "Z"(*(unsigned char *)(addr + off)) : "memory"); +// CHECK-LABEL: void @testZwOff(i8* %addr, i64 %off) +// CHECK: %[[VAL:[^ ]+]] = getelementptr i8, i8* %addr, i64 %off +// CHECK: call void asm sideeffect "dcbz ${0:y}\0A", "*Z,~{memory}"(i8* %[[VAL]]) +} -- 2.7.4