Author: Albion Fung Date: 2021-07-11T22:02:30-05:00 New Revision: b7df33f4ada9cbfa4ac2bb2b251497dc12e4d648
URL: https://github.com/llvm/llvm-project/commit/b7df33f4ada9cbfa4ac2bb2b251497dc12e4d648 DIFF: https://github.com/llvm/llvm-project/commit/b7df33f4ada9cbfa4ac2bb2b251497dc12e4d648.diff LOG: [PowerPC] Fix L[D|W]ARX Implementation LDARX and LWARX sometimes gets optimized out by the compiler when it is critical to the correctness of the code. This inline asm generation ensures that it preserved. Differential Revision: https://reviews.llvm.org/D105754 Added: Modified: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vadd.c clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c llvm/include/llvm/IR/IntrinsicsPowerPC.td llvm/lib/Target/PowerPC/PPCInstr64Bit.td llvm/lib/Target/PowerPC/PPCInstrInfo.td llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond-64bit-only.ll llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond.ll Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 41ea2bf5f43a..ed81523540b2 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -994,6 +994,46 @@ static llvm::Value *EmitBitTestIntrinsic(CodeGenFunction &CGF, ShiftedByte, llvm::ConstantInt::get(CGF.Int8Ty, 1), "bittest.res"); } +static llvm::Value *emitPPCLoadReserveIntrinsic(CodeGenFunction &CGF, + unsigned BuiltinID, + const CallExpr *E) { + Value *Addr = CGF.EmitScalarExpr(E->getArg(0)); + + SmallString<64> Asm; + raw_svector_ostream AsmOS(Asm); + llvm::IntegerType *RetType = CGF.Int32Ty; + + switch (BuiltinID) { + case clang::PPC::BI__builtin_ppc_ldarx: + AsmOS << "ldarx "; + RetType = CGF.Int64Ty; + break; + case clang::PPC::BI__builtin_ppc_lwarx: + AsmOS << "lwarx "; + RetType = CGF.Int32Ty; + break; + default: + llvm_unreachable("Expected only PowerPC load reserve intrinsics"); + } + + AsmOS << "$0, ${1:y}"; + + std::string Constraints = "=r,*Z,~{memory}"; + std::string MachineClobbers = CGF.getTarget().getClobbers(); + if (!MachineClobbers.empty()) { + Constraints += ','; + Constraints += MachineClobbers; + } + + llvm::Type *IntPtrType = RetType->getPointerTo(); + llvm::FunctionType *FTy = + llvm::FunctionType::get(RetType, {IntPtrType}, false); + + llvm::InlineAsm *IA = + llvm::InlineAsm::get(FTy, Asm, Constraints, /*hasSideEffects=*/true); + return CGF.Builder.CreateCall(IA, {Addr}); +} + namespace { enum class MSVCSetJmpKind { _setjmpex, @@ -15532,6 +15572,9 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E, llvm::AtomicOrdering::Monotonic); } + case PPC::BI__builtin_ppc_ldarx: + case PPC::BI__builtin_ppc_lwarx: + return emitPPCLoadReserveIntrinsic(*this, BuiltinID, E); } } diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vadd.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vadd.c index ae3a2305fd71..9e050e044c30 100644 --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vadd.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-overloaded/vadd.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d -target-feature +experimental-v \ -// RUN: -target-feature +experimental-zfh -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s +// RUN: -target-feature +experimental-zfh -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg --mtriple=riscv64 | FileCheck --check-prefix=CHECK-RV64 %s #include <riscv_vector.h> diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c b/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c index 80bb4de424a1..f0a8ff184311 100644 --- a/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c +++ b/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond-64bit-only.c @@ -1,27 +1,23 @@ // RUN: not %clang_cc1 -triple=powerpc-unknown-aix -emit-llvm %s -o - 2>&1 |\ // RUN: FileCheck %s --check-prefix=CHECK32-ERROR -// RUN: %clang_cc1 -triple=powerpc64-unknown-aix -emit-llvm %s -o - | \ +// RUN: %clang_cc1 -O2 -triple=powerpc64-unknown-aix -emit-llvm %s -o - | \ // RUN: FileCheck %s --check-prefix=CHECK64 -// RUN: %clang_cc1 -triple=powerpc64le-unknown-unknown -emit-llvm %s \ +// RUN: %clang_cc1 -O2 -triple=powerpc64le-unknown-unknown -emit-llvm %s \ // RUN: -o - | FileCheck %s --check-prefix=CHECK64 -// RUN: %clang_cc1 -triple=powerpc64-unknown-unknown -emit-llvm %s \ +// RUN: %clang_cc1 -O2 -triple=powerpc64-unknown-unknown -emit-llvm %s \ // RUN: -o - | FileCheck %s --check-prefix=CHECK64 long test_ldarx(volatile long* a) { // CHECK64-LABEL: @test_ldarx - // CHECK64: %0 = load i64*, i64** %a.addr, align 8 - // CHECK64: %1 = bitcast i64* %0 to i8* - // CHECK64: %2 = call i64 @llvm.ppc.ldarx(i8* %1) + // CHECK64: %0 = tail call i64 asm sideeffect "ldarx $0, ${1:y}", "=r,*Z,~{memory}"(i64* %a) // CHECK32-ERROR: error: this builtin is only available on 64-bit targets return __ldarx(a); } int test_stdcx(volatile long* addr, long val) { // CHECK64-LABEL: @test_stdcx - // CHECK64: %0 = load i64*, i64** %addr.addr, align 8 - // CHECK64: %1 = bitcast i64* %0 to i8* - // CHECK64: %2 = load i64, i64* %val.addr, align 8 - // CHECK64: %3 = call i32 @llvm.ppc.stdcx(i8* %1, i64 %2) + // CHECK64: %0 = bitcast i64* %addr to i8* + // CHECK64: %1 = tail call i32 @llvm.ppc.stdcx(i8* %0, i64 %val) // CHECK32-ERROR: error: this builtin is only available on 64-bit targets return __stdcx(addr, val); } diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c b/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c index 5b807973894e..4ffa29a09455 100644 --- a/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c +++ b/clang/test/CodeGen/builtins-ppc-xlcompat-LoadReseve-StoreCond.c @@ -1,22 +1,20 @@ -// RUN: %clang_cc1 -triple=powerpc-unknown-aix -emit-llvm %s -o - | \ +// RUN: %clang_cc1 -O2 -triple=powerpc-unknown-aix -emit-llvm %s -o - | \ // RUN: FileCheck %s -// RUN: %clang_cc1 -triple=powerpc64-unknown-aix -emit-llvm %s -o - | \ +// RUN: %clang_cc1 -O2 -triple=powerpc64-unknown-aix -emit-llvm %s -o - | \ // RUN: FileCheck %s -// RUN: %clang_cc1 -triple=powerpc64le-unknown-unknown -emit-llvm %s \ +// RUN: %clang_cc1 -O2 -triple=powerpc64le-unknown-unknown -emit-llvm %s \ // RUN: -o - | FileCheck %s -// RUN: %clang_cc1 -triple=powerpc64-unknown-unknown -emit-llvm %s \ +// RUN: %clang_cc1 -O2 -triple=powerpc64-unknown-unknown -emit-llvm %s \ // RUN: -o - | FileCheck %s int test_lwarx(volatile int* a) { // CHECK: @test_lwarx - // CHECK: %1 = bitcast i32* %0 to i8* - // CHECK: %2 = call i32 @llvm.ppc.lwarx(i8* %1) + // CHECK: %0 = tail call i32 asm sideeffect "lwarx $0, ${1:y}", "=r,*Z,~{memory}"(i32* %a) return __lwarx(a); } int test_stwcx(volatile int* a, int val) { // CHECK: @test_stwcx - // CHECK: %1 = bitcast i32* %0 to i8* - // CHECK: %2 = load i32, i32* %val.addr, align 4 - // CHECK: %3 = call i32 @llvm.ppc.stwcx(i8* %1, i32 %2) + // CHECK: %0 = bitcast i32* %a to i8* + // CHECK: %1 = tail call i32 @llvm.ppc.stwcx(i8* %0, i32 %val) return __stwcx(a, val); } diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td index ad6a1e8d1a7a..3ed156d7137e 100644 --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -1529,9 +1529,5 @@ let TargetPrefix = "ppc" in { def int_ppc_stwcx : GCCBuiltin<"__builtin_ppc_stwcx">, Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrWriteMem]>; - def int_ppc_lwarx : GCCBuiltin<"__builtin_ppc_lwarx">, - Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>; - def int_ppc_ldarx : GCCBuiltin<"__builtin_ppc_ldarx">, - Intrinsic<[llvm_i64_ty], [llvm_ptr_ty], [IntrNoMem]>; } diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td index dc6a0c1a30e1..ac6f4e5844a5 100644 --- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td @@ -1723,5 +1723,3 @@ def SLBSYNC : XForm_0<31, 338, (outs), (ins), "slbsync", IIC_SprSLBSYNC, []>; def : Pat<(int_ppc_stdcx ForceXForm:$dst, g8rc:$A), (STDCX g8rc:$A, ForceXForm:$dst)>; -def : Pat<(int_ppc_ldarx ForceXForm:$dst), - (LDARX ForceXForm:$dst)>; diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index 20429ee664b2..8d59cd8185c5 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -5412,7 +5412,5 @@ def DWBytes3210 { def : Pat<(i64 (bitreverse i64:$A)), (OR8 (RLDICR DWBytes7654.DWord, 32, 31), DWBytes3210.DWord)>; -def : Pat<(int_ppc_lwarx ForceXForm:$dst), - (LWARX ForceXForm:$dst)>; def : Pat<(int_ppc_stwcx ForceXForm:$dst, gprc:$A), (STWCX gprc:$A, ForceXForm:$dst)>; diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond-64bit-only.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond-64bit-only.ll index d845a1cea152..675641d55fe5 100644 --- a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond-64bit-only.ll +++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond-64bit-only.ll @@ -10,17 +10,18 @@ declare i64 @llvm.ppc.ldarx(i8*) define dso_local i64 @test_ldarx(i64* readnone %a) { ; CHECK-LABEL: test_ldarx: ; CHECK: # %bb.0: # %entry +; CHECK-NEXT: #APP ; CHECK-NEXT: ldarx 3, 0, 3 +; CHECK-NEXT: #NO_APP ; CHECK-NEXT: blr entry: - %0 = bitcast i64* %a to i8* - %1 = tail call i64 @llvm.ppc.ldarx(i8* %0) - ret i64 %1 + %0 = call i64 asm sideeffect "ldarx $0, $1", "=r,*Z,~{memory}"(i64* %a) + ret i64 %0 } declare i32 @llvm.ppc.stdcx(i8*, i64) -define dso_local i64 @test(i64* %a, i64 %b) { -; CHECK-LABEL: test: +define dso_local i64 @test_stdcx(i64* %a, i64 %b) { +; CHECK-LABEL: test_stdcx: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: stdcx. 4, 0, 3 ; CHECK-NEXT: mfocrf 3, 128 diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond.ll index 462b57f5f7a4..a29f02cc5164 100644 --- a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond.ll +++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond.ll @@ -12,18 +12,21 @@ declare i32 @llvm.ppc.lwarx(i8*) define dso_local signext i32 @test_lwarx(i32* readnone %a) { ; CHECK-64-LABEL: test_lwarx: ; CHECK-64: # %bb.0: # %entry +; CHECK-64-NEXT: #APP ; CHECK-64-NEXT: lwarx 3, 0, 3 +; CHECK-64-NEXT: #NO_APP ; CHECK-64-NEXT: extsw 3, 3 ; CHECK-64-NEXT: blr ; ; CHECK-32-LABEL: test_lwarx: ; CHECK-32: # %bb.0: # %entry +; CHECK-32-NEXT: #APP ; CHECK-32-NEXT: lwarx 3, 0, 3 +; CHECK-32-NEXT: #NO_APP ; CHECK-32-NEXT: blr entry: - %0 = bitcast i32* %a to i8* - %1 = tail call i32 @llvm.ppc.lwarx(i8* %0) - ret i32 %1 + %0 = call i32 asm sideeffect "lwarx $0, $1", "=r,*Z,~{memory}"(i32* %a) + ret i32 %0 } declare i32 @llvm.ppc.stwcx(i8*, i32) _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits