| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 |
| ; RUN: llc -mtriple=powerpc-unknown-linux-gnu -O0 < %s | FileCheck %s --check-prefix=PPC |
| ; RUN: llc -mcpu=ppc -mtriple=powerpc64-unknown-linux-gnu -O0 < %s | FileCheck %s --check-prefix=PPC64 |
| ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -O0 < %s | FileCheck %s --check-prefix=PPC64LE |
| |
| ; Testing operations in soft-float mode |
| define double @foo() #0 { |
| ; PPC-LABEL: foo: |
| ; PPC: # %bb.0: # %entry |
| ; PPC-NEXT: mflr 0 |
| ; PPC-NEXT: stwu 1, -32(1) |
| ; PPC-NEXT: stw 0, 36(1) |
| ; PPC-NEXT: lwz 3, 24(1) |
| ; PPC-NEXT: lwz 4, 28(1) |
| ; PPC-NEXT: lwz 5, 16(1) |
| ; PPC-NEXT: lwz 6, 20(1) |
| ; PPC-NEXT: bl __adddf3 |
| ; PPC-NEXT: lwz 0, 36(1) |
| ; PPC-NEXT: addi 1, 1, 32 |
| ; PPC-NEXT: mtlr 0 |
| ; PPC-NEXT: blr |
| ; |
| ; PPC64-LABEL: foo: |
| ; PPC64: # %bb.0: # %entry |
| ; PPC64-NEXT: mflr 0 |
| ; PPC64-NEXT: stdu 1, -128(1) |
| ; PPC64-NEXT: std 0, 144(1) |
| ; PPC64-NEXT: ld 3, 120(1) |
| ; PPC64-NEXT: ld 4, 112(1) |
| ; PPC64-NEXT: bl __adddf3 |
| ; PPC64-NEXT: nop |
| ; PPC64-NEXT: addi 1, 1, 128 |
| ; PPC64-NEXT: ld 0, 16(1) |
| ; PPC64-NEXT: mtlr 0 |
| ; PPC64-NEXT: blr |
| ; |
| ; PPC64LE-LABEL: foo: |
| ; PPC64LE: # %bb.0: # %entry |
| ; PPC64LE-NEXT: mflr 0 |
| ; PPC64LE-NEXT: stdu 1, -48(1) |
| ; PPC64LE-NEXT: std 0, 64(1) |
| ; PPC64LE-NEXT: ld 3, 40(1) |
| ; PPC64LE-NEXT: ld 4, 32(1) |
| ; PPC64LE-NEXT: bl __adddf3 |
| ; PPC64LE-NEXT: nop |
| ; PPC64LE-NEXT: addi 1, 1, 48 |
| ; PPC64LE-NEXT: ld 0, 16(1) |
| ; PPC64LE-NEXT: mtlr 0 |
| ; PPC64LE-NEXT: blr |
| entry: |
| %a = alloca double, align 8 |
| %b = alloca double, align 8 |
| %0 = load double, ptr %a, align 8 |
| %1 = load double, ptr %b, align 8 |
| %add = fadd double %0, %1 |
| ret double %add |
| } |
| |
| define double @foo1() #0 { |
| ; PPC-LABEL: foo1: |
| ; PPC: # %bb.0: # %entry |
| ; PPC-NEXT: mflr 0 |
| ; PPC-NEXT: stwu 1, -32(1) |
| ; PPC-NEXT: stw 0, 36(1) |
| ; PPC-NEXT: lwz 3, 24(1) |
| ; PPC-NEXT: lwz 4, 28(1) |
| ; PPC-NEXT: lwz 5, 16(1) |
| ; PPC-NEXT: lwz 6, 20(1) |
| ; PPC-NEXT: bl __muldf3 |
| ; PPC-NEXT: lwz 0, 36(1) |
| ; PPC-NEXT: addi 1, 1, 32 |
| ; PPC-NEXT: mtlr 0 |
| ; PPC-NEXT: blr |
| ; |
| ; PPC64-LABEL: foo1: |
| ; PPC64: # %bb.0: # %entry |
| ; PPC64-NEXT: mflr 0 |
| ; PPC64-NEXT: stdu 1, -128(1) |
| ; PPC64-NEXT: std 0, 144(1) |
| ; PPC64-NEXT: ld 3, 120(1) |
| ; PPC64-NEXT: ld 4, 112(1) |
| ; PPC64-NEXT: bl __muldf3 |
| ; PPC64-NEXT: nop |
| ; PPC64-NEXT: addi 1, 1, 128 |
| ; PPC64-NEXT: ld 0, 16(1) |
| ; PPC64-NEXT: mtlr 0 |
| ; PPC64-NEXT: blr |
| ; |
| ; PPC64LE-LABEL: foo1: |
| ; PPC64LE: # %bb.0: # %entry |
| ; PPC64LE-NEXT: mflr 0 |
| ; PPC64LE-NEXT: stdu 1, -48(1) |
| ; PPC64LE-NEXT: std 0, 64(1) |
| ; PPC64LE-NEXT: ld 3, 40(1) |
| ; PPC64LE-NEXT: ld 4, 32(1) |
| ; PPC64LE-NEXT: bl __muldf3 |
| ; PPC64LE-NEXT: nop |
| ; PPC64LE-NEXT: addi 1, 1, 48 |
| ; PPC64LE-NEXT: ld 0, 16(1) |
| ; PPC64LE-NEXT: mtlr 0 |
| ; PPC64LE-NEXT: blr |
| entry: |
| %a = alloca double, align 8 |
| %b = alloca double, align 8 |
| %0 = load double, ptr %a, align 8 |
| %1 = load double, ptr %b, align 8 |
| %mul = fmul double %0, %1 |
| ret double %mul |
| } |
| |
| define double @foo2() #0 { |
| ; PPC-LABEL: foo2: |
| ; PPC: # %bb.0: # %entry |
| ; PPC-NEXT: mflr 0 |
| ; PPC-NEXT: stwu 1, -32(1) |
| ; PPC-NEXT: stw 0, 36(1) |
| ; PPC-NEXT: lwz 3, 24(1) |
| ; PPC-NEXT: lwz 4, 28(1) |
| ; PPC-NEXT: lwz 5, 16(1) |
| ; PPC-NEXT: lwz 6, 20(1) |
| ; PPC-NEXT: bl __subdf3 |
| ; PPC-NEXT: lwz 0, 36(1) |
| ; PPC-NEXT: addi 1, 1, 32 |
| ; PPC-NEXT: mtlr 0 |
| ; PPC-NEXT: blr |
| ; |
| ; PPC64-LABEL: foo2: |
| ; PPC64: # %bb.0: # %entry |
| ; PPC64-NEXT: mflr 0 |
| ; PPC64-NEXT: stdu 1, -128(1) |
| ; PPC64-NEXT: std 0, 144(1) |
| ; PPC64-NEXT: ld 3, 120(1) |
| ; PPC64-NEXT: ld 4, 112(1) |
| ; PPC64-NEXT: bl __subdf3 |
| ; PPC64-NEXT: nop |
| ; PPC64-NEXT: addi 1, 1, 128 |
| ; PPC64-NEXT: ld 0, 16(1) |
| ; PPC64-NEXT: mtlr 0 |
| ; PPC64-NEXT: blr |
| ; |
| ; PPC64LE-LABEL: foo2: |
| ; PPC64LE: # %bb.0: # %entry |
| ; PPC64LE-NEXT: mflr 0 |
| ; PPC64LE-NEXT: stdu 1, -48(1) |
| ; PPC64LE-NEXT: std 0, 64(1) |
| ; PPC64LE-NEXT: ld 3, 40(1) |
| ; PPC64LE-NEXT: ld 4, 32(1) |
| ; PPC64LE-NEXT: bl __subdf3 |
| ; PPC64LE-NEXT: nop |
| ; PPC64LE-NEXT: addi 1, 1, 48 |
| ; PPC64LE-NEXT: ld 0, 16(1) |
| ; PPC64LE-NEXT: mtlr 0 |
| ; PPC64LE-NEXT: blr |
| entry: |
| %a = alloca double, align 8 |
| %b = alloca double, align 8 |
| %0 = load double, ptr %a, align 8 |
| %1 = load double, ptr %b, align 8 |
| %sub = fsub double %0, %1 |
| ret double %sub |
| } |
| |
| define double @foo3() #0 { |
| ; PPC-LABEL: foo3: |
| ; PPC: # %bb.0: # %entry |
| ; PPC-NEXT: mflr 0 |
| ; PPC-NEXT: stwu 1, -32(1) |
| ; PPC-NEXT: stw 0, 36(1) |
| ; PPC-NEXT: lwz 3, 24(1) |
| ; PPC-NEXT: lwz 4, 28(1) |
| ; PPC-NEXT: lwz 5, 16(1) |
| ; PPC-NEXT: lwz 6, 20(1) |
| ; PPC-NEXT: bl __divdf3 |
| ; PPC-NEXT: lwz 0, 36(1) |
| ; PPC-NEXT: addi 1, 1, 32 |
| ; PPC-NEXT: mtlr 0 |
| ; PPC-NEXT: blr |
| ; |
| ; PPC64-LABEL: foo3: |
| ; PPC64: # %bb.0: # %entry |
| ; PPC64-NEXT: mflr 0 |
| ; PPC64-NEXT: stdu 1, -128(1) |
| ; PPC64-NEXT: std 0, 144(1) |
| ; PPC64-NEXT: ld 3, 120(1) |
| ; PPC64-NEXT: ld 4, 112(1) |
| ; PPC64-NEXT: bl __divdf3 |
| ; PPC64-NEXT: nop |
| ; PPC64-NEXT: addi 1, 1, 128 |
| ; PPC64-NEXT: ld 0, 16(1) |
| ; PPC64-NEXT: mtlr 0 |
| ; PPC64-NEXT: blr |
| ; |
| ; PPC64LE-LABEL: foo3: |
| ; PPC64LE: # %bb.0: # %entry |
| ; PPC64LE-NEXT: mflr 0 |
| ; PPC64LE-NEXT: stdu 1, -48(1) |
| ; PPC64LE-NEXT: std 0, 64(1) |
| ; PPC64LE-NEXT: ld 3, 40(1) |
| ; PPC64LE-NEXT: ld 4, 32(1) |
| ; PPC64LE-NEXT: bl __divdf3 |
| ; PPC64LE-NEXT: nop |
| ; PPC64LE-NEXT: addi 1, 1, 48 |
| ; PPC64LE-NEXT: ld 0, 16(1) |
| ; PPC64LE-NEXT: mtlr 0 |
| ; PPC64LE-NEXT: blr |
| entry: |
| %a = alloca double, align 8 |
| %b = alloca double, align 8 |
| %0 = load double, ptr %a, align 8 |
| %1 = load double, ptr %b, align 8 |
| %div = fdiv double %0, %1 |
| ret double %div |
| } |
| |
| ; Function Attrs: noinline nounwind optnone uwtable |
| define dso_local zeroext i32 @func(double noundef %0, double noundef %1) #0 { |
| ; PPC-LABEL: func: |
| ; PPC: # %bb.0: |
| ; PPC-NEXT: mflr 0 |
| ; PPC-NEXT: stwu 1, -32(1) |
| ; PPC-NEXT: stw 0, 36(1) |
| ; PPC-NEXT: # kill: def $r7 killed $r6 |
| ; PPC-NEXT: # kill: def $r7 killed $r5 |
| ; PPC-NEXT: # kill: def $r7 killed $r4 |
| ; PPC-NEXT: # kill: def $r7 killed $r3 |
| ; PPC-NEXT: stw 4, 28(1) |
| ; PPC-NEXT: stw 3, 24(1) |
| ; PPC-NEXT: stw 6, 20(1) |
| ; PPC-NEXT: stw 5, 16(1) |
| ; PPC-NEXT: lwz 3, 24(1) |
| ; PPC-NEXT: stw 3, 8(1) # 4-byte Folded Spill |
| ; PPC-NEXT: lwz 3, 28(1) |
| ; PPC-NEXT: stw 3, 12(1) # 4-byte Folded Spill |
| ; PPC-NEXT: lwz 3, 16(1) |
| ; PPC-NEXT: lwz 4, 20(1) |
| ; PPC-NEXT: lis 5, -15888 |
| ; PPC-NEXT: li 6, 0 |
| ; PPC-NEXT: bl __muldf3 |
| ; PPC-NEXT: mr 5, 3 |
| ; PPC-NEXT: lwz 3, 8(1) # 4-byte Folded Reload |
| ; PPC-NEXT: mr 6, 4 |
| ; PPC-NEXT: lwz 4, 12(1) # 4-byte Folded Reload |
| ; PPC-NEXT: bl __adddf3 |
| ; PPC-NEXT: bl __fixunsdfsi |
| ; PPC-NEXT: lwz 0, 36(1) |
| ; PPC-NEXT: addi 1, 1, 32 |
| ; PPC-NEXT: mtlr 0 |
| ; PPC-NEXT: blr |
| ; |
| ; PPC64-LABEL: func: |
| ; PPC64: # %bb.0: |
| ; PPC64-NEXT: mflr 0 |
| ; PPC64-NEXT: stdu 1, -144(1) |
| ; PPC64-NEXT: std 0, 160(1) |
| ; PPC64-NEXT: std 3, 136(1) |
| ; PPC64-NEXT: std 4, 128(1) |
| ; PPC64-NEXT: ld 3, 136(1) |
| ; PPC64-NEXT: std 3, 120(1) # 8-byte Folded Spill |
| ; PPC64-NEXT: ld 3, 128(1) |
| ; PPC64-NEXT: li 4, 3103 |
| ; PPC64-NEXT: rldic 4, 4, 52, 0 |
| ; PPC64-NEXT: bl __muldf3 |
| ; PPC64-NEXT: nop |
| ; PPC64-NEXT: mr 4, 3 |
| ; PPC64-NEXT: ld 3, 120(1) # 8-byte Folded Reload |
| ; PPC64-NEXT: bl __adddf3 |
| ; PPC64-NEXT: nop |
| ; PPC64-NEXT: bl __fixunsdfsi |
| ; PPC64-NEXT: nop |
| ; PPC64-NEXT: # kill: def $r3 killed $r3 killed $x3 |
| ; PPC64-NEXT: clrldi 3, 3, 32 |
| ; PPC64-NEXT: addi 1, 1, 144 |
| ; PPC64-NEXT: ld 0, 16(1) |
| ; PPC64-NEXT: mtlr 0 |
| ; PPC64-NEXT: blr |
| ; |
| ; PPC64LE-LABEL: func: |
| ; PPC64LE: # %bb.0: |
| ; PPC64LE-NEXT: mflr 0 |
| ; PPC64LE-NEXT: stdu 1, -64(1) |
| ; PPC64LE-NEXT: std 0, 80(1) |
| ; PPC64LE-NEXT: std 3, 56(1) |
| ; PPC64LE-NEXT: std 4, 48(1) |
| ; PPC64LE-NEXT: ld 3, 56(1) |
| ; PPC64LE-NEXT: std 3, 40(1) # 8-byte Folded Spill |
| ; PPC64LE-NEXT: ld 3, 48(1) |
| ; PPC64LE-NEXT: li 4, 3103 |
| ; PPC64LE-NEXT: rldic 4, 4, 52, 0 |
| ; PPC64LE-NEXT: bl __muldf3 |
| ; PPC64LE-NEXT: nop |
| ; PPC64LE-NEXT: mr 4, 3 |
| ; PPC64LE-NEXT: ld 3, 40(1) # 8-byte Folded Reload |
| ; PPC64LE-NEXT: bl __adddf3 |
| ; PPC64LE-NEXT: nop |
| ; PPC64LE-NEXT: bl __fixunsdfsi |
| ; PPC64LE-NEXT: nop |
| ; PPC64LE-NEXT: # kill: def $r3 killed $r3 killed $x3 |
| ; PPC64LE-NEXT: clrldi 3, 3, 32 |
| ; PPC64LE-NEXT: addi 1, 1, 64 |
| ; PPC64LE-NEXT: ld 0, 16(1) |
| ; PPC64LE-NEXT: mtlr 0 |
| ; PPC64LE-NEXT: blr |
| %3 = alloca double, align 8 |
| %4 = alloca double, align 8 |
| store double %0, ptr %3, align 8 |
| store double %1, ptr %4, align 8 |
| %5 = load double, ptr %3, align 8 |
| %6 = load double, ptr %4, align 8 |
| %7 = fneg double %6 |
| %8 = call double @llvm.fmuladd.f64(double %7, double 0x41F0000000000000, double %5) |
| %9 = fptoui double %8 to i32 |
| ret i32 %9 |
| } |
| |
| ; To check ppc_fp128 soften without crash |
| define zeroext i1 @ppcf128_soften(ppc_fp128 %a) #0 { |
| ; PPC-LABEL: ppcf128_soften: |
| ; PPC: # %bb.0: # %entry |
| ; PPC-NEXT: stwu 1, -16(1) |
| ; PPC-NEXT: stw 5, 8(1) # 4-byte Folded Spill |
| ; PPC-NEXT: mr 5, 4 |
| ; PPC-NEXT: lwz 4, 8(1) # 4-byte Folded Reload |
| ; PPC-NEXT: stw 5, 12(1) # 4-byte Folded Spill |
| ; PPC-NEXT: mr 5, 3 |
| ; PPC-NEXT: lwz 3, 12(1) # 4-byte Folded Reload |
| ; PPC-NEXT: # kill: def $r4 killed $r3 |
| ; PPC-NEXT: # kill: def $r4 killed $r5 |
| ; PPC-NEXT: xoris 4, 5, 65520 |
| ; PPC-NEXT: or 4, 3, 4 |
| ; PPC-NEXT: cntlzw 4, 4 |
| ; PPC-NEXT: clrlwi 5, 5, 1 |
| ; PPC-NEXT: or 3, 3, 5 |
| ; PPC-NEXT: cntlzw 3, 3 |
| ; PPC-NEXT: or 3, 3, 4 |
| ; PPC-NEXT: srwi 3, 3, 5 |
| ; PPC-NEXT: addi 1, 1, 16 |
| ; PPC-NEXT: blr |
| ; |
| ; PPC64-LABEL: ppcf128_soften: |
| ; PPC64: # %bb.0: # %entry |
| ; PPC64-NEXT: li 4, 4095 |
| ; PPC64-NEXT: rldic 4, 4, 52, 0 |
| ; PPC64-NEXT: cmpld 7, 3, 4 |
| ; PPC64-NEXT: mfcr 4 # cr7 |
| ; PPC64-NEXT: rlwinm 4, 4, 31, 31, 31 |
| ; PPC64-NEXT: clrldi 3, 3, 1 |
| ; PPC64-NEXT: cmpldi 7, 3, 0 |
| ; PPC64-NEXT: mfcr 3 # cr7 |
| ; PPC64-NEXT: rlwinm 3, 3, 31, 31, 31 |
| ; PPC64-NEXT: or 4, 3, 4 |
| ; PPC64-NEXT: # implicit-def: $x3 |
| ; PPC64-NEXT: mr 3, 4 |
| ; PPC64-NEXT: clrldi 3, 3, 32 |
| ; PPC64-NEXT: blr |
| ; |
| ; PPC64LE-LABEL: ppcf128_soften: |
| ; PPC64LE: # %bb.0: # %entry |
| ; PPC64LE-NEXT: li 3, 4095 |
| ; PPC64LE-NEXT: rldic 3, 3, 52, 0 |
| ; PPC64LE-NEXT: cmpd 4, 3 |
| ; PPC64LE-NEXT: crmove 21, 2 |
| ; PPC64LE-NEXT: clrldi. 3, 4, 1 |
| ; PPC64LE-NEXT: crmove 20, 2 |
| ; PPC64LE-NEXT: cror 20, 20, 21 |
| ; PPC64LE-NEXT: li 4, 0 |
| ; PPC64LE-NEXT: li 3, 1 |
| ; PPC64LE-NEXT: isel 3, 3, 4, 20 |
| ; PPC64LE-NEXT: blr |
| entry: |
| %fpclass = tail call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %a, i32 100) |
| ret i1 %fpclass |
| } |
| |
| ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) |
| declare double @llvm.fmuladd.f64(double, double, double) #1 |
| declare i1 @llvm.is.fpclass.ppcf128(ppc_fp128, i32 immarg) #1 |
| |
| attributes #0 = {"use-soft-float"="true" nounwind } |
| attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } |