[llvm-branch-commits] [clang] b7df33f - [PowerPC] Fix L[D|W]ARX Implementation
Albion Fung via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Jul 11 20:02:46 PDT 2021
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)
More information about the llvm-branch-commits
mailing list