Skip to content

[PowerPC] Implement 32-bit expansion for rldimi #86783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17297,6 +17297,16 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
Value *Op1 = EmitScalarExpr(E->getArg(1));
Value *Op2 = EmitScalarExpr(E->getArg(2));
Value *Op3 = EmitScalarExpr(E->getArg(3));
// rldimi is 64-bit instruction, expand the intrinsic before isel to
// leverage peephole and avoid legalization efforts.
if (BuiltinID == PPC::BI__builtin_ppc_rldimi &&
!getTarget().getTriple().isPPC64()) {
Function *F = CGM.getIntrinsic(Intrinsic::fshl, Op0->getType());
Op2 = Builder.CreateZExt(Op2, Int64Ty);
Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op2});
return Builder.CreateOr(Builder.CreateAnd(Shift, Op3),
Builder.CreateAnd(Op1, Builder.CreateNot(Op3)));
}
return Builder.CreateCall(
CGM.getIntrinsic(BuiltinID == PPC::BI__builtin_ppc_rldimi
? Intrinsic::ppc_rldimi
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5236,7 +5236,6 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
case PPC::BI__builtin_ppc_fetch_and_andlp:
case PPC::BI__builtin_ppc_fetch_and_orlp:
case PPC::BI__builtin_ppc_fetch_and_swaplp:
case PPC::BI__builtin_ppc_rldimi:
return true;
}
return false;
Expand Down
6 changes: 0 additions & 6 deletions clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-error.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ void test_trap(void) {
__tw(ia, ib, 0); //expected-error {{argument value 0 is outside the valid range [1, 31]}}
}

#ifdef __PPC64__
void test_builtin_ppc_rldimi() {
unsigned int shift;
unsigned long long mask;
Expand All @@ -33,7 +32,6 @@ void test_builtin_ppc_rldimi() {
res = __builtin_ppc_rldimi(ull, ull, 63, 0xFFFF000000000F00); // expected-error {{argument 3 value should represent a contiguous bit field}}
res = __builtin_ppc_rldimi(ull, ull, 64, 0xFFFF000000000000); // expected-error {{argument value 64 is outside the valid range [0, 63]}}
}
#endif

void test_builtin_ppc_rlwimi() {
unsigned int shift;
Expand Down Expand Up @@ -86,10 +84,6 @@ void testalignx(const void *pointer, unsigned int alignment) {
}

#ifndef __PPC64__
unsigned long long testrldimi32() {
return __rldimi(ull, ui, 3, 0x7ffff8ULL); //expected-error {{this builtin is only available on 64-bit targets}}
}

long long testbpermd(long long bit_selector, long long source) {
return __bpermd(bit_selector, source); //expected-error {{this builtin is only available on 64-bit targets}}
}
Expand Down
7 changes: 3 additions & 4 deletions llvm/include/llvm/IR/IntrinsicsPowerPC.td
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,6 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_fctuwz
: ClangBuiltin<"__builtin_ppc_fctuwz">,
DefaultAttrsIntrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
def int_ppc_rldimi
: ClangBuiltin<"__builtin_ppc_rldimi">,
DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i64_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
def int_ppc_rlwimi
: ClangBuiltin<"__builtin_ppc_rlwimi">,
DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
Expand All @@ -194,6 +190,9 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
: ClangBuiltin<"__builtin_ppc_rlwnm">,
DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_ppc_rldimi
: DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i64_ty],
[IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;

// XL compatible select functions
// TODO: Add llvm_f128_ty support.
Expand Down
154 changes: 154 additions & 0 deletions llvm/test/CodeGen/PowerPC/rldimi.ll
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,158 @@ define i64 @rldimi11(i64 %a, i64 %b) {
ret i64 %r
}

define i64 @rldimi12(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi12:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 20
; CHECK-NEXT: rldimi 4, 3, 44, 31
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 0, i64 18446726490113441791)
ret i64 %r
}

define i64 @rldimi13(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi13:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 62
; CHECK-NEXT: rldimi 4, 3, 32, 2
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 30, i64 4611686014132420608)
ret i64 %r
}

define i64 @rldimi14(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi14:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 23
; CHECK-NEXT: rldimi 4, 3, 53, 0
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 18437736874454810624) ; mb=0, me=10
ret i64 %r
}

define i64 @rldimi15(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi15:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 36
; CHECK-NEXT: rldimi 4, 3, 40, 10
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 18013298997854208) ; mb=10, me=23
ret i64 %r
}

define i64 @rldimi16(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi16:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 57
; CHECK-NEXT: rldimi 4, 3, 19, 10
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 18014398508957696) ; mb=10, me=44
ret i64 %r
}

define i64 @rldimi17(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi17:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 43
; CHECK-NEXT: rldimi 4, 3, 33, 25
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 541165879296) ; mb=25, me=30
ret i64 %r
}

define i64 @rldimi18(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi18:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 57
; CHECK-NEXT: rldimi 4, 3, 19, 25
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 549755289600) ; mb=25, me=44
ret i64 %r
}

define i64 @rldimi19(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi19:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 57
; CHECK-NEXT: rldimi 4, 3, 19, 33
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 2146959360) ; mb=33, me=44
ret i64 %r
}

define i64 @rldimi20(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi20:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 23
; CHECK-NEXT: rldimi 4, 3, 53, 15
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 18438299824408231935) ; mb=15, me=10
ret i64 %r
}

define i64 @rldimi21(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi21:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 23
; CHECK-NEXT: rldimi 4, 3, 53, 25
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 18437737424210624511) ; mb=25, me=10
ret i64 %r
}

define i64 @rldimi22(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi22:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 34
; CHECK-NEXT: rldimi 4, 3, 42, 25
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 18446740225418854399) ; mb=25, me=21
ret i64 %r
}

define i64 @rldimi23(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi23:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 23
; CHECK-NEXT: rldimi 4, 3, 53, 44
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 18437736874455859199) ; mb=44, me=10
ret i64 %r
}

define i64 @rldimi24(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi24:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 38
; CHECK-NEXT: rldimi 4, 3, 38, 44
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 18446743798832693247) ; mb=44, me=25
ret i64 %r
}

define i64 @rldimi25(i64 %a, i64 %b) {
; CHECK-LABEL: rldimi25:
; CHECK: # %bb.0:
; CHECK-NEXT: rotldi 3, 3, 48
; CHECK-NEXT: rldimi 4, 3, 28, 44
; CHECK-NEXT: mr 3, 4
; CHECK-NEXT: blr
%r = call i64 @llvm.ppc.rldimi(i64 %a, i64 %b, i32 12, i64 18446744073442164735) ; mb=44, me=35
ret i64 %r
}

declare i64 @llvm.ppc.rldimi(i64, i64, i32 immarg, i64 immarg)