Conanap created this revision. Herald added subscribers: shchenz, kbarton, hiraditya, nemanjai. Conanap requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D105754 Files: clang/lib/CodeGen/CGBuiltin.cpp llvm/include/llvm/IR/IntrinsicsPowerPC.td llvm/lib/Target/PowerPC/PPCInstr64Bit.td llvm/lib/Target/PowerPC/PPCInstrInfo.td Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td =================================================================== --- llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -5412,7 +5412,5 @@ 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)>; Index: llvm/lib/Target/PowerPC/PPCInstr64Bit.td =================================================================== --- llvm/lib/Target/PowerPC/PPCInstr64Bit.td +++ llvm/lib/Target/PowerPC/PPCInstr64Bit.td @@ -1723,5 +1723,3 @@ def : Pat<(int_ppc_stdcx ForceXForm:$dst, g8rc:$A), (STDCX g8rc:$A, ForceXForm:$dst)>; -def : Pat<(int_ppc_ldarx ForceXForm:$dst), - (LDARX ForceXForm:$dst)>; Index: llvm/include/llvm/IR/IntrinsicsPowerPC.td =================================================================== --- llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -1529,9 +1529,5 @@ 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]>; } Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -994,6 +994,44 @@ ShiftedByte, llvm::ConstantInt::get(CGF.Int8Ty, 1), "bittest.res"); } +static llvm::Value *emitLoadReserveIntrinsic(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; + } + + AsmOS << "$0, $1"; + + 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, @@ -5103,6 +5141,9 @@ Str.getPointer(), Zeros); return RValue::get(Ptr); } + case clang::PPC::BI__builtin_ppc_ldarx: + case clang::PPC::BI__builtin_ppc_lwarx: + return RValue::get(emitLoadReserveIntrinsic(*this, BuiltinID, E)); } // If this is an alias for a lib function (e.g. __builtin_sin), emit
Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td =================================================================== --- llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -5412,7 +5412,5 @@ 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)>; Index: llvm/lib/Target/PowerPC/PPCInstr64Bit.td =================================================================== --- llvm/lib/Target/PowerPC/PPCInstr64Bit.td +++ llvm/lib/Target/PowerPC/PPCInstr64Bit.td @@ -1723,5 +1723,3 @@ def : Pat<(int_ppc_stdcx ForceXForm:$dst, g8rc:$A), (STDCX g8rc:$A, ForceXForm:$dst)>; -def : Pat<(int_ppc_ldarx ForceXForm:$dst), - (LDARX ForceXForm:$dst)>; Index: llvm/include/llvm/IR/IntrinsicsPowerPC.td =================================================================== --- llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -1529,9 +1529,5 @@ 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]>; } Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -994,6 +994,44 @@ ShiftedByte, llvm::ConstantInt::get(CGF.Int8Ty, 1), "bittest.res"); } +static llvm::Value *emitLoadReserveIntrinsic(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; + } + + AsmOS << "$0, $1"; + + 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, @@ -5103,6 +5141,9 @@ Str.getPointer(), Zeros); return RValue::get(Ptr); } + case clang::PPC::BI__builtin_ppc_ldarx: + case clang::PPC::BI__builtin_ppc_lwarx: + return RValue::get(emitLoadReserveIntrinsic(*this, BuiltinID, E)); } // If this is an alias for a lib function (e.g. __builtin_sin), emit
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits