[PowerPC] Add PowerPC compare and multiply related builtins and instrinsics for XL compatibility

This patch is in a series of patches to provide builtins for compatibility
with the XL compiler. This patch adds the builtins and instrisics for compare
and multiply related operations.

Reviewed By: nemanjai, #powerpc

Differential revision: https://reviews.llvm.org/D102875
This commit is contained in:
Victor Huang 2021-07-13 14:57:08 -05:00
parent f2b5e438aa
commit 18c19414eb
15 changed files with 429 additions and 0 deletions

View File

@ -71,6 +71,18 @@ BUILTIN(__builtin_ppc_fctiw, "dd", "")
BUILTIN(__builtin_ppc_fctiwz, "dd", "")
BUILTIN(__builtin_ppc_fctudz, "dd", "")
BUILTIN(__builtin_ppc_fctuwz, "dd", "")
// Compare
BUILTIN(__builtin_ppc_cmpeqb, "LLiLLiLLi", "")
BUILTIN(__builtin_ppc_cmprb, "iCIiii", "")
BUILTIN(__builtin_ppc_setb, "LLiLLiLLi", "")
// Multiply
BUILTIN(__builtin_ppc_mulhd, "LLiLiLi", "")
BUILTIN(__builtin_ppc_mulhdu, "ULLiULiULi", "")
BUILTIN(__builtin_ppc_mulhw, "iii", "")
BUILTIN(__builtin_ppc_mulhwu, "UiUiUi", "")
BUILTIN(__builtin_ppc_maddhd, "LLiLLiLLiLLi", "")
BUILTIN(__builtin_ppc_maddhdu, "ULLiULLiULLiULLi", "")
BUILTIN(__builtin_ppc_maddld, "LLiLLiLLiLLi", "")
BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")

View File

@ -130,6 +130,16 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
Builder.defineMacro("__fctiwz", "__builtin_ppc_fctiwz");
Builder.defineMacro("__fctudz", "__builtin_ppc_fctudz");
Builder.defineMacro("__fctuwz", "__builtin_ppc_fctuwz");
Builder.defineMacro("__cmpeqb", "__builtin_ppc_cmpeqb");
Builder.defineMacro("__cmprb", "__builtin_ppc_cmprb");
Builder.defineMacro("__setb", "__builtin_ppc_setb");
Builder.defineMacro("__mulhd", "__builtin_ppc_mulhd");
Builder.defineMacro("__mulhdu", "__builtin_ppc_mulhdu");
Builder.defineMacro("__mulhw", "__builtin_ppc_mulhw");
Builder.defineMacro("__mulhwu", "__builtin_ppc_mulhwu");
Builder.defineMacro("__maddhd", "__builtin_ppc_maddhd");
Builder.defineMacro("__maddhdu", "__builtin_ppc_maddhdu");
Builder.defineMacro("__maddld", "__builtin_ppc_maddld");
}
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific

View File

@ -3269,6 +3269,13 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
case PPC::BI__builtin_ppc_stdcx:
case PPC::BI__builtin_ppc_tdw:
case PPC::BI__builtin_ppc_trapd:
case PPC::BI__builtin_ppc_cmpeqb:
case PPC::BI__builtin_ppc_setb:
case PPC::BI__builtin_ppc_mulhd:
case PPC::BI__builtin_ppc_mulhdu:
case PPC::BI__builtin_ppc_maddhd:
case PPC::BI__builtin_ppc_maddhdu:
case PPC::BI__builtin_ppc_maddld:
return true;
}
return false;
@ -3360,6 +3367,17 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
case PPC::BI__builtin_ppc_tw:
case PPC::BI__builtin_ppc_tdw:
return SemaBuiltinConstantArgRange(TheCall, 2, 0, 31);
case PPC::BI__builtin_ppc_cmpeqb:
case PPC::BI__builtin_ppc_setb:
case PPC::BI__builtin_ppc_maddhd:
case PPC::BI__builtin_ppc_maddhdu:
case PPC::BI__builtin_ppc_maddld:
return SemaFeatureCheck(*this, TheCall, "isa-v30-instructions",
diag::err_ppc_builtin_only_on_arch, "9");
case PPC::BI__builtin_ppc_cmprb:
return SemaFeatureCheck(*this, TheCall, "isa-v30-instructions",
diag::err_ppc_builtin_only_on_arch, "9") ||
SemaBuiltinConstantArgRange(TheCall, 0, 0, 1);
#define CUSTOM_BUILTIN(Name, Intr, Types, Acc) \
case PPC::BI__builtin_##Name: \
return SemaBuiltinPPCMMACall(TheCall, Types);

View File

@ -0,0 +1,25 @@
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown \
// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
// RUN: not %clang_cc1 -triple powerpc-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 2>&1 | FileCheck %s --check-prefix=CHECK-32-ERROR
extern long int sli;
extern unsigned long int uli;
long long test_builtin_ppc_mulhd() {
// CHECK-LABEL: @test_builtin_ppc_mulhd(
// CHECK: %2 = call i64 @llvm.ppc.mulhd(i64 %0, i64 %1)
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
return __builtin_ppc_mulhd(sli, sli);
}
unsigned long long test_builtin_ppc_mulhdu() {
// CHECK-LABEL: @test_builtin_ppc_mulhdu(
// CHECK: %2 = call i64 @llvm.ppc.mulhdu(i64 %0, i64 %1)
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
return __builtin_ppc_mulhdu(uli, uli);
}

View File

@ -0,0 +1,23 @@
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown \
// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s
// RUN: %clang_cc1 -triple powerpc-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
extern int si;
extern unsigned int ui;
int test_builtin_ppc_mulhw() {
// CHECK-LABEL: @test_builtin_ppc_mulhw(
// CHECK: %2 = call i32 @llvm.ppc.mulhw(i32 %0, i32 %1)
return __builtin_ppc_mulhw(si, si);
}
unsigned int test_builtin_ppc_mulhwu() {
// CHECK-LABEL: @test_builtin_ppc_mulhwu(
// CHECK: %2 = call i32 @llvm.ppc.mulhwu(i32 %0, i32 %1)
return __builtin_ppc_mulhwu(ui, ui);
}

View File

@ -0,0 +1,61 @@
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm %s \
// RUN: -target-cpu pwr9 -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -emit-llvm %s \
// RUN: -target-cpu pwr9 -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s \
// RUN: -target-cpu pwr9 -o - | FileCheck %s
// RUN: not %clang_cc1 -triple powerpc-unknown-aix %s -emit-llvm %s \
// RUN: -target-cpu pwr9 2>&1 | FileCheck %s --check-prefix=CHECK-32-ERROR
// RUN: not %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s \
// RUN: -target-cpu pwr8 2>&1 | FileCheck %s --check-prefix=CHECK-NONPWR9-ERR
extern signed long long sll;
extern unsigned long long ull;
signed long long test_builtin_ppc_cmpeqb() {
// CHECK-LABEL: @test_builtin_ppc_cmpeqb(
// CHECK: %2 = call i64 @llvm.ppc.cmpeqb(i64 %0, i64 %1)
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
return __builtin_ppc_cmpeqb(sll, sll);
}
long long test_builtin_ppc_setb() {
// CHECK-LABEL: @test_builtin_ppc_setb(
// CHECK: %2 = call i64 @llvm.ppc.setb(i64 %0, i64 %1)
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
return __builtin_ppc_setb(sll, sll);
}
signed long long test_builtin_ppc_maddhd() {
// CHECK-LABEL: @test_builtin_ppc_maddhd(
// CHECK: %3 = call i64 @llvm.ppc.maddhd(i64 %0, i64 %1, i64 %2)
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
return __builtin_ppc_maddhd(sll, sll, sll);
}
unsigned long long test_builtin_ppc_maddhdu() {
// CHECK-LABEL: @test_builtin_ppc_maddhdu(
// CHECK: %3 = call i64 @llvm.ppc.maddhdu(i64 %0, i64 %1, i64 %2)
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
return __builtin_ppc_maddhdu(ull, ull, ull);
}
signed long long test_builtin_ppc_maddld() {
// CHECK-LABEL: @test_builtin_ppc_maddld(
// CHECK: %3 = call i64 @llvm.ppc.maddld(i64 %0, i64 %1, i64 %2)
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
return __builtin_ppc_maddld(sll, sll, sll);
}
unsigned long long test_builtin_ppc_maddld_unsigned() {
// CHECK-LABEL: @test_builtin_ppc_maddld_unsigned(
// CHECK: %3 = call i64 @llvm.ppc.maddld(i64 %0, i64 %1, i64 %2)
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
return __builtin_ppc_maddld(ull, ull, ull);
}

View File

@ -0,0 +1,15 @@
// REQUIRES: powerpc-registered-target
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu pwr9 \
// RUN: -fsyntax-only -Wall -Werror -verify %s
// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr9 \
// RUN: -fsyntax-only -Wall -Werror -verify %s
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -target-cpu pwr9 \
// RUN: -fsyntax-only -Wall -Werror -verify %s
// RUN: %clang_cc1 -triple powerpc-unknown-aix -target-cpu pwr9 \
// RUN: -fsyntax-only -Wall -Werror -verify %s
extern unsigned int ui;
void test_builtin_ppc_cmprb() {
int res = __builtin_ppc_cmprb(3, ui, ui); // expected-error {{argument value 3 is outside the valid range [0, 1]}}
}

View File

@ -0,0 +1,20 @@
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm %s \
// RUN: -target-cpu pwr9 -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -emit-llvm %s \
// RUN: -target-cpu pwr9 -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s \
// RUN: -target-cpu pwr9 -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc-unknown-aix %s -emit-llvm %s \
// RUN: -target-cpu pwr9 -o - | FileCheck %s
// RUN: not %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s \
// RUN: -target-cpu pwr8 2>&1 | FileCheck %s --check-prefix=CHECK-NONPWR9-ERR
extern unsigned int ui;
int test_builtin_ppc_cmprb() {
// CHECK-LABEL: @test_builtin_ppc_cmprb(
// CHECK: %2 = call i32 @llvm.ppc.cmprb(i32 0, i32 %0, i32 %1)
// CHECK: %5 = call i32 @llvm.ppc.cmprb(i32 1, i32 %3, i32 %4)
// CHECK-NONPWR9-ERR: error: this builtin is only valid on POWER9 or later CPUs
return __builtin_ppc_cmprb(0, ui, ui) + __builtin_ppc_cmprb(1, ui, ui);
}

View File

@ -1565,5 +1565,38 @@ let TargetPrefix = "ppc" in {
def int_ppc_stwcx : GCCBuiltin<"__builtin_ppc_stwcx">,
Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty],
[IntrWriteMem]>;
// compare
def int_ppc_cmpeqb
: GCCBuiltin<"__builtin_ppc_cmpeqb">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
def int_ppc_cmprb
: GCCBuiltin<"__builtin_ppc_cmprb">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<0>>]>;
def int_ppc_setb
: GCCBuiltin<"__builtin_ppc_setb">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
// multiply
def int_ppc_mulhd
: GCCBuiltin<"__builtin_ppc_mulhd">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
def int_ppc_mulhdu
: GCCBuiltin<"__builtin_ppc_mulhdu">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
def int_ppc_mulhw
: GCCBuiltin<"__builtin_ppc_mulhw">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_ppc_mulhwu
: GCCBuiltin<"__builtin_ppc_mulhwu">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_ppc_maddhd
: GCCBuiltin<"__builtin_ppc_maddhd">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
def int_ppc_maddhdu
: GCCBuiltin<"__builtin_ppc_maddhdu">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
def int_ppc_maddld
: GCCBuiltin<"__builtin_ppc_maddld">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
}

View File

@ -1689,6 +1689,26 @@ def : Pat<(atomic_load_64 XForm:$src), (LDX memrr:$src)>;
def : Pat<(atomic_store_64 DSForm:$ptr, i64:$val), (STD g8rc:$val, memrix:$ptr)>;
def : Pat<(atomic_store_64 XForm:$ptr, i64:$val), (STDX g8rc:$val, memrr:$ptr)>;
let Predicates = [IsISA3_0, In64BitMode] in {
def : Pat<(i64 (int_ppc_cmpeqb g8rc:$a, g8rc:$b)),
(i64 (SETB8 (CMPEQB $a, $b)))>;
def : Pat<(i64 (int_ppc_setb g8rc:$a, g8rc:$b)),
(i64 (SETB8 (CMPD $a, $b)))>;
def : Pat<(i64 (int_ppc_maddhd g8rc:$a, g8rc:$b, g8rc:$c)),
(i64 (MADDHD $a, $b, $c))>;
def : Pat<(i64 (int_ppc_maddhdu g8rc:$a, g8rc:$b, g8rc:$c)),
(i64 (MADDHDU $a, $b, $c))>;
def : Pat<(i64 (int_ppc_maddld g8rc:$a, g8rc:$b, g8rc:$c)),
(i64 (MADDLD8 $a, $b, $c))>;
}
let Predicates = [In64BitMode] in {
def : Pat<(i64 (int_ppc_mulhd g8rc:$a, g8rc:$b)),
(i64 (MULHD $a, $b))>;
def : Pat<(i64 (int_ppc_mulhdu g8rc:$a, g8rc:$b)),
(i64 (MULHDU $a, $b))>;
}
let Predicates = [IsISA3_0] in {
// DARN (deliver random number)
// L=0 for 32-bit, L=1 for conditioned random, L=2 for raw random

View File

@ -5260,6 +5260,15 @@ def SETB : XForm_44<31, 128, (outs gprc:$RT), (ins crrc:$BFA),
"setb $RT, $BFA", IIC_IntGeneral>;
} // IsISA3_0
let Predicates = [IsISA3_0] in {
def : Pat<(i32 (int_ppc_cmprb i32:$a, gprc:$b, gprc:$c)),
(i32 (SETB (CMPRB u1imm:$a, $b, $c)))>;
}
def : Pat<(i32 (int_ppc_mulhw gprc:$a, gprc:$b)),
(i32 (MULHW $a, $b))>;
def : Pat<(i32 (int_ppc_mulhwu gprc:$a, gprc:$b)),
(i32 (MULHWU $a, $b))>;
// Fast 32-bit reverse bits algorithm:
// Step 1: 1-bit swap (swap odd 1-bit and even 1-bit):
// n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xAAAAAAAA);

View File

@ -0,0 +1,33 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
; RUN: -mcpu=pwr9 < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
; RUN: -mcpu=pwr9 < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
; RUN: -mcpu=pwr9 < %s | FileCheck %s
define dso_local i64 @test_builtin_ppc_cmpeqb(i64 %a, i64 %b) {
; CHECK-LABEL: test_builtin_ppc_cmpeqb:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: cmpeqb 0, 3, 4
; CHECK-NEXT: setb 3, 0
; CHECK-NEXT: blr
entry:
%0 = call i64 @llvm.ppc.cmpeqb(i64 %a, i64 %b)
ret i64 %0
}
declare i64 @llvm.ppc.cmpeqb(i64, i64)
define dso_local i64 @test_builtin_ppc_setb(i64 %a, i64 %b) {
; CHECK-LABEL: test_builtin_ppc_setb:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: cmpd 3, 4
; CHECK-NEXT: setb 3, 0
; CHECK-NEXT: blr
entry:
%0 = call i64 @llvm.ppc.setb(i64 %a, i64 %b)
ret i64 %0
}
declare i64 @llvm.ppc.setb(i64, i64)

View File

@ -0,0 +1,37 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64
; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-32
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64
define dso_local signext i32 @test_builtin_ppc_cmprb(i32 %a, i32%b, i32 %c, i32%d) {
; CHECK-32-LABEL: test_builtin_ppc_cmprb:
; CHECK-32: # %bb.0: # %entry
; CHECK-32-NEXT: cmprb 0, 0, 3, 4
; CHECK-32-NEXT: setb 3, 0
; CHECK-32-NEXT: cmprb 0, 1, 5, 6
; CHECK-32-NEXT: setb 4, 0
; CHECK-32-NEXT: add 3, 3, 4
; CHECK-32-NEXT: blr
;
; CHECK-64-LABEL: test_builtin_ppc_cmprb:
; CHECK-64: # %bb.0: # %entry
; CHECK-64-NEXT: cmprb 0, 0, 3, 4
; CHECK-64-NEXT: setb 3, 0
; CHECK-64-NEXT: cmprb 0, 1, 5, 6
; CHECK-64-NEXT: setb 4, 0
; CHECK-64-NEXT: add 3, 3, 4
; CHECK-64-NEXT: extsw 3, 3
; CHECK-64-NEXT: blr
entry:
%0 = call i32 @llvm.ppc.cmprb(i32 0, i32 %a, i32 %b)
%1 = call i32 @llvm.ppc.cmprb(i32 1, i32 %c, i32 %d)
%add = add nsw i32 %0, %1
ret i32 %add
}
declare i32 @llvm.ppc.cmprb(i32, i32, i32)

View File

@ -0,0 +1,68 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
; RUN: -mcpu=pwr9 < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
; RUN: -mcpu=pwr9 < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
; RUN: -mcpu=pwr9 < %s | FileCheck %s
define dso_local i64 @test_builtin_ppc_mulhd(i64 %a, i64 %b) {
; CHECK-LABEL: test_builtin_ppc_mulhd:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: mulhd 3, 3, 4
; CHECK-NEXT: blr
entry:
%0 = call i64 @llvm.ppc.mulhd(i64 %a, i64 %b)
ret i64 %0
}
declare i64 @llvm.ppc.mulhd(i64, i64)
define dso_local i64 @test_builtin_ppc_mulhdu(i64 %a, i64 %b) {
; CHECK-LABEL: test_builtin_ppc_mulhdu:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: mulhdu 3, 3, 4
; CHECK-NEXT: blr
entry:
%0 = call i64 @llvm.ppc.mulhdu(i64 %a, i64 %b)
ret i64 %0
}
declare i64 @llvm.ppc.mulhdu(i64, i64)
define dso_local i64 @test_builtin_ppc_maddhd(i64 %a, i64 %b, i64 %c) {
; CHECK-LABEL: test_builtin_ppc_maddhd:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: maddhd 3, 3, 4, 5
; CHECK-NEXT: blr
entry:
%0 = call i64 @llvm.ppc.maddhd(i64 %a, i64 %b, i64 %c)
ret i64 %0
}
declare i64 @llvm.ppc.maddhd(i64, i64, i64)
define dso_local i64 @test_builtin_ppc_maddhdu(i64 %a, i64 %b, i64 %c) {
; CHECK-LABEL: test_builtin_ppc_maddhdu:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: maddhdu 3, 3, 4, 5
; CHECK-NEXT: blr
entry:
%0 = call i64 @llvm.ppc.maddhdu(i64 %a, i64 %b, i64 %c)
ret i64 %0
}
declare i64 @llvm.ppc.maddhdu(i64, i64, i64)
define dso_local i64 @test_builtin_ppc_maddld(i64 %a, i64 %b, i64 %c) {
; CHECK-LABEL: test_builtin_ppc_maddld:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: maddld 3, 3, 4, 5
; CHECK-NEXT: blr
entry:
%0 = call i64 @llvm.ppc.maddld(i64 %a, i64 %b, i64 %c)
ret i64 %0
}
declare i64 @llvm.ppc.maddld(i64, i64, i64)

View File

@ -0,0 +1,45 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64
; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-32
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64
define dso_local signext i32 @test_builtin_ppc_mulhw(i32 %a, i32%b) {
; CHECK-32-LABEL: test_builtin_ppc_mulhw:
; CHECK-32: # %bb.0: # %entry
; CHECK-32-NEXT: mulhw 3, 3, 4
; CHECK-32-NEXT: blr
;
; CHECK-64-LABEL: test_builtin_ppc_mulhw:
; CHECK-64: # %bb.0: # %entry
; CHECK-64-NEXT: mulhw 3, 3, 4
; CHECK-64-NEXT: extsw 3, 3
; CHECK-64-NEXT: blr
entry:
%0 = call i32 @llvm.ppc.mulhw(i32 %a, i32 %b)
ret i32 %0
}
declare i32 @llvm.ppc.mulhw(i32, i32)
define dso_local zeroext i32 @test_builtin_ppc_mulhwu(i32 %a, i32%b) {
; CHECK-32-LABEL: test_builtin_ppc_mulhwu:
; CHECK-32: # %bb.0: # %entry
; CHECK-32-NEXT: mulhwu 3, 3, 4
; CHECK-32-NEXT: blr
;
; CHECK-64-LABEL: test_builtin_ppc_mulhwu:
; CHECK-64: # %bb.0: # %entry
; CHECK-64-NEXT: mulhwu 3, 3, 4
; CHECK-64-NEXT: clrldi 3, 3, 32
; CHECK-64-NEXT: blr
entry:
%0 = call i32 @llvm.ppc.mulhwu(i32 %a, i32 %b)
ret i32 %0
}
declare i32 @llvm.ppc.mulhwu(i32, i32)