quinnp created this revision. Herald added subscribers: shchenz, kbarton, hiraditya, nemanjai. quinnp requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
Most of the builtins already had intrinsics and only needed to be implemented in the front end. Intrinsics were created for the three iospace builtins, eieio, and icbt. Pseudo instructions were created for eieio and iospace_eieio to ensure that nops were inserted before the eieio instruction. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D102443 Files: clang/include/clang/Basic/BuiltinsPPC.def clang/test/CodeGen/builtins-ppc-xlcompat-sync.c llvm/include/llvm/IR/IntrinsicsPowerPC.td llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp llvm/lib/Target/PowerPC/PPCInstrInfo.td llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-msync.ll llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-sync.ll llvm/test/CodeGen/PowerPC/eieio.ll
Index: llvm/test/CodeGen/PowerPC/eieio.ll =================================================================== --- llvm/test/CodeGen/PowerPC/eieio.ll +++ llvm/test/CodeGen/PowerPC/eieio.ll @@ -4,7 +4,9 @@ define void @eieio_test() { ; CHECK-LABEL: @eieio_test -; CHECK: eieio +; CHECK: ori r2, r2, 0 +; CHECK-NEXT: ori r2, r2, 0 +; CHECK-NEXT: eieio ; CHECK-NEXT: blr entry: Index: llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-sync.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-sync.ll @@ -0,0 +1,74 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpcle-unknown-linux-gnu \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-linux-gnu \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s + +define dso_local void @test_builtin_ppc_eieio() #0 { +; CHECK-LABEL: test_builtin_ppc_eieio + +entry: + call void @llvm.ppc.eieio() +; CHECK: ori 2, 2, 0 +; CHECK-NEXT: ori 2, 2, 0 +; CHECK-NEXT: eieio + + ret void +} + +declare void @llvm.ppc.eieio() #2 + +define dso_local void @test_builtin_ppc_iospace_eieio() #0 { +; CHECK-LABEL: test_builtin_ppc_iospace_eieio + +entry: + call void @llvm.ppc.iospace.eieio() +; CHECK: ori 2, 2, 0 +; CHECK-NEXT: ori 2, 2, 0 +; CHECK-NEXT: eieio + + ret void +} + +declare void @llvm.ppc.iospace.eieio() #2 + +define dso_local void @test_builtin_ppc_iospace_lwsync() #0 { +; CHECK-LABEL: test_builtin_ppc_iospace_lwsync + +entry: + call void @llvm.ppc.iospace.lwsync() +; CHECK: lwsync + + ret void +} + +declare void @llvm.ppc.iospace.lwsync() #2 + +define dso_local void @test_builtin_ppc_iospace_sync() #0 { +; CHECK-LABEL: test_builtin_ppc_iospace_sync + +entry: + call void @llvm.ppc.iospace.sync() +; CHECK: sync + + ret void +} + +declare void @llvm.ppc.iospace.sync() #2 + +define dso_local void @test_builtin_ppc_icbt() #0 { +; CHECK-LABEL: test_builtin_ppc_icbt + +entry: + %a = alloca i8*, align 8 + %0 = load i8*, i8** %a, align 8 + call void @llvm.ppc.icbt(i8* %0) +; CHECK: icbt 0, 0, 3 + + ret void +} + +declare void @llvm.ppc.icbt(i8*) #2 Index: llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-msync.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-msync.ll @@ -0,0 +1,33 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpcle-unknown-linux-gnu \ +; RUN: -mattr=+msync -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-linux-gnu \ +; RUN: -mattr=+msync -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mattr=+msync -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mattr=+msync -mcpu=pwr8 < %s | FileCheck %s + +define dso_local void @test_builtin_ppc_iospace_lwsync() #0 { +; CHECK-LABEL: test_builtin_ppc_iospace_lwsync + +entry: + call void @llvm.ppc.iospace.lwsync() +; CHECK: msync + + ret void +} + +declare void @llvm.ppc.iospace.lwsync() #2 + +define dso_local void @test_builtin_ppc_iospace_sync() #0 { +; CHECK-LABEL: test_builtin_ppc_iospace_sync + +entry: + call void @llvm.ppc.iospace.sync() +; CHECK: msync + + ret void +} + +declare void @llvm.ppc.iospace.sync() #2 + Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td =================================================================== --- llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -2019,6 +2019,8 @@ (DCBTST 0, xoaddr:$dst)>; def : Pat<(int_ppc_dcbf xoaddr:$dst), (DCBF 0, xoaddr:$dst)>; +def : Pat<(int_ppc_icbt xoaddr:$dst), + (ICBT 0, xoaddr:$dst)>; def : Pat<(prefetch xoaddr:$dst, (i32 0), imm, (i32 1)), (DCBT 0, xoaddr:$dst)>; // data prefetch for loads @@ -2540,11 +2542,21 @@ def EnforceIEIO : XForm_24_eieio<31, 854, (outs), (ins), "eieio", IIC_LdStLoad, []>; +def PseudoEIEIO : PPCEmitTimePseudo<(outs), (ins), "#PPCEIEIO", + [(int_ppc_eieio)]>; +def PseudoIOSPACEEIEIO : PPCEmitTimePseudo<(outs), (ins), "#PPCIOSPACEEIEIO", + [(int_ppc_iospace_eieio)]>; + def : Pat<(int_ppc_sync), (SYNC 0)>, Requires<[HasSYNC]>; +def : Pat<(int_ppc_iospace_sync), (SYNC 0)>, Requires<[HasSYNC]>; def : Pat<(int_ppc_lwsync), (SYNC 1)>, Requires<[HasSYNC]>; +def : Pat<(int_ppc_iospace_lwsync), (SYNC 1)>, Requires<[HasSYNC]>; def : Pat<(int_ppc_sync), (MSYNC)>, Requires<[HasOnlyMSYNC]>; +def : Pat<(int_ppc_iospace_sync), (MSYNC)>, Requires<[HasOnlyMSYNC]>; def : Pat<(int_ppc_lwsync), (MSYNC)>, Requires<[HasOnlyMSYNC]>; +def : Pat<(int_ppc_iospace_lwsync), (MSYNC)>, Requires<[HasOnlyMSYNC]>; def : Pat<(int_ppc_eieio), (EnforceIEIO)>; +def : Pat<(int_ppc_iospace_eieio), (EnforceIEIO)>; //===----------------------------------------------------------------------===// // PPC32 Arithmetic Instructions. Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -1352,6 +1352,19 @@ // Now process the instruction normally. break; } + case PPC::PseudoEIEIO: + case PPC::PseudoIOSPACEEIEIO: { + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI) + .addReg(PPC::X2) + .addReg(PPC::X2) + .addImm(0)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI) + .addReg(PPC::X2) + .addReg(PPC::X2) + .addImm(0)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::EnforceIEIO)); + return; + } } LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); Index: llvm/include/llvm/IR/IntrinsicsPowerPC.td =================================================================== --- llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -20,34 +20,53 @@ def int_ppc_dcba : Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbf : GCCBuiltin<"__builtin_dcbf">, Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; - def int_ppc_dcbfl : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; - def int_ppc_dcbflp : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; + def int_ppc_dcbfl : GCCBuiltin<"__dcbfl">, + Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; + def int_ppc_dcbflp : GCCBuiltin<"__dcbflp">, + Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; def int_ppc_dcbfps : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; def int_ppc_dcbstps : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; def int_ppc_dcbi : Intrinsic<[], [llvm_ptr_ty], []>; - def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>; - def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty], + def int_ppc_dcbst : GCCBuiltin<"__dcbst">, + Intrinsic<[], [llvm_ptr_ty], []>; + def int_ppc_dcbt : GCCBuiltin<"__dcbt">, + Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>; - def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty], + def int_ppc_dcbtst : GCCBuiltin<"__dcbtst">, + Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>; def int_ppc_dcbt_with_hint: Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrArgMemOnly, NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>; def int_ppc_dcbtst_with_hint: Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrArgMemOnly, NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>; - def int_ppc_dcbz : Intrinsic<[], [llvm_ptr_ty], []>; + def int_ppc_dcbz : GCCBuiltin<"__dcbz">, + Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>; + def int_ppc_icbt : GCCBuiltin<"__icbt">, + Intrinsic<[], [llvm_ptr_ty], []>; // Population Count in each Byte. - def int_ppc_popcntb : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>; + def int_ppc_popcntb : GCCBuiltin<"__popcntb">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>; // sync instruction (i.e. sync 0, a.k.a hwsync) - def int_ppc_sync : Intrinsic<[], [], []>; + def int_ppc_sync : GCCBuiltin<"__sync">, + Intrinsic<[], [], []>; + def int_ppc_iospace_sync : GCCBuiltin<"__iospace_sync">, + Intrinsic<[], [], []>; // isync instruction - def int_ppc_isync : Intrinsic<[], [], []>; + def int_ppc_isync : GCCBuiltin<"__isync">, + Intrinsic<[], [], []>; // lwsync is sync 1 - def int_ppc_lwsync : Intrinsic<[], [], []>; + def int_ppc_lwsync : GCCBuiltin<"__lwsync">, + Intrinsic<[], [], []>; + def int_ppc_iospace_lwsync : GCCBuiltin<"__iospace_lwsync">, + Intrinsic<[], [], []>; // eieio instruction - def int_ppc_eieio : Intrinsic<[],[],[]>; + def int_ppc_eieio : GCCBuiltin<"__eieio">, + Intrinsic<[],[],[]>; + def int_ppc_iospace_eieio : GCCBuiltin<"__iospace_eieio">, + Intrinsic<[],[],[]>; // Get content from current FPSCR register def int_ppc_readflm : GCCBuiltin<"__builtin_readflm">, Index: clang/test/CodeGen/builtins-ppc-xlcompat-sync.c =================================================================== --- /dev/null +++ clang/test/CodeGen/builtins-ppc-xlcompat-sync.c @@ -0,0 +1,133 @@ +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s + +void test_builtin_ppc_popcntb() { +// CHECK-LABEL: @test_builtin_ppc_popcntb( +// CHECK-NEXT: entry: + + unsigned long a; + unsigned long b = __popcntb(a); +// CHECK: %1 = call i64 @llvm.ppc.popcntb(i64 %0) +} + +void test_builtin_ppc_eieio() { +// CHECK-LABEL: @test_builtin_ppc_eieio( +// CHECK-NEXT: entry: + + __eieio(); +// CHECK: call void @llvm.ppc.eieio() +} + +void test_builtin_ppc_iospace_eieio() { +// CHECK-LABEL: @test_builtin_ppc_iospace_eieio( +// CHECK-NEXT: entry: + + __iospace_eieio(); +// CHECK: call void @llvm.ppc.iospace.eieio() +} + +void test_builtin_ppc_isync() { +// CHECK-LABEL: @test_builtin_ppc_isync( +// CHECK-NEXT: entry: + + __isync(); +// CHECK: call void @llvm.ppc.isync() +} + +void test_builtin_ppc_lwsync() { +// CHECK-LABEL: @test_builtin_ppc_lwsync( +// CHECK-NEXT: entry: + + __lwsync(); +// CHECK: call void @llvm.ppc.lwsync() +} + +void test_builtin_ppc_iospace_lwsync() { +// CHECK-LABEL: @test_builtin_ppc_iospace_lwsync( +// CHECK-NEXT: entry: + + __iospace_lwsync(); +// CHECK: call void @llvm.ppc.iospace.lwsync() +} + +void test_builtin_ppc_sync() { +// CHECK-LABEL: @test_builtin_ppc_sync( +// CHECK-NEXT: entry: + + __sync(); +// CHECK: call void @llvm.ppc.sync() +} + +void test_builtin_ppc_iospace_sync() { +// CHECK-LABEL: @test_builtin_ppc_iospace_sync( +// CHECK-NEXT: entry: + + __iospace_sync(); +// CHECK: call void @llvm.ppc.iospace.sync() +} + +void test_builtin_ppc_dcbfl() { +// CHECK-LABEL: @test_builtin_ppc_dcbfl( +// CHECK-NEXT: entry: + + const void* a; + __dcbfl(a); +// CHECK: call void @llvm.ppc.dcbfl(i8* %0) +} + +void test_builtin_ppc_dcbflp() { +// CHECK-LABEL: @test_builtin_ppc_dcbflp( +// CHECK-NEXT: entry: + + const void* a; + __dcbflp(a); +// CHECK: call void @llvm.ppc.dcbflp(i8* %0) +} + +void test_builtin_ppc_dcbst() { +// CHECK-LABEL: @test_builtin_ppc_dcbst( +// CHECK-NEXT: entry: + + const void* a; + __dcbst(a); +// CHECK: call void @llvm.ppc.dcbst(i8* %0) +} + +void test_builtin_ppc_dcbt() { +// CHECK-LABEL: @test_builtin_ppc_dcbt( +// CHECK-NEXT: entry: + + void* a; + __dcbt(a); +// CHECK: call void @llvm.ppc.dcbt(i8* %0) +} + +void test_builtin_ppc_dcbtst() { +// CHECK-LABEL: @test_builtin_ppc_dcbtst( +// CHECK-NEXT: entry: + + void* a; + __dcbtst(a); +// CHECK: call void @llvm.ppc.dcbtst(i8* %0) +} + +void test_builtin_ppc_dcbz() { +// CHECK-LABEL: @test_builtin_ppc_dcbz( +// CHECK-NEXT: entry: + + void* a; + __dcbz(a); +// CHECK: call void @llvm.ppc.dcbz(i8* %0) +} + +void test_builtin_ppc_icbt() { +// CHECK-LABEL: @test_builtin_ppc_icbt( +// CHECK-NEXT: entry: + + void* a; + __icbt(a); +// CHECK: call void @llvm.ppc.icbt(i8* %0) +} + Index: clang/include/clang/Basic/BuiltinsPPC.def =================================================================== --- clang/include/clang/Basic/BuiltinsPPC.def +++ clang/include/clang/Basic/BuiltinsPPC.def @@ -29,6 +29,22 @@ #define UNALIASED_CUSTOM_BUILTIN(ID, TYPES, ACCUMULATE) \ CUSTOM_BUILTIN(ID, ID, TYPES, ACCUMULATE) +BUILTIN(__popcntb, "ULiULi", "") +BUILTIN(__eieio, "v", "") +BUILTIN(__iospace_eieio, "v", "") +BUILTIN(__isync, "v", "") +BUILTIN(__lwsync, "v", "") +BUILTIN(__iospace_lwsync, "v", "") +BUILTIN(__sync, "v", "") +BUILTIN(__iospace_sync, "v", "") +BUILTIN(__dcbfl, "vvC*", "") +BUILTIN(__dcbflp, "vvC*", "") +BUILTIN(__dcbst, "vvC*", "") +BUILTIN(__dcbt, "vv*", "") +BUILTIN(__dcbtst, "vv*", "") +BUILTIN(__dcbz, "vv*", "") +BUILTIN(__icbt, "vv*", "") + BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n") // This is just a placeholder, the types and attributes are wrong.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits