| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: split-file %s %t |
| ; RUN: llc -verify-machineinstrs < %t/single.ll -mtriple=powerpc-unknown-linux-gnu \ |
| ; RUN: -mattr=+spe | FileCheck %t/single.ll |
| ; RUN: llc -verify-machineinstrs < %t/double.ll -mtriple=powerpc-unknown-linux-gnu \ |
| ; RUN: -mattr=+spe | FileCheck %t/double.ll -check-prefix=SPE |
| ; RUN: llc -verify-machineinstrs < %t/hwdouble.ll -mtriple=powerpc-unknown-linux-gnu \ |
| ; RUN: -mattr=+spe | FileCheck %t/hwdouble.ll -check-prefix=SPE |
| ; RUN: llc -verify-machineinstrs < %t/single.ll -mtriple=powerpc-unknown-linux-gnu \ |
| ; RUN: -mattr=+efpu2 | FileCheck %t/single.ll |
| ; RUN: llc -verify-machineinstrs < %t/double.ll -mtriple=powerpc-unknown-linux-gnu \ |
| ; RUN: -mattr=+efpu2 | FileCheck %t/double.ll -check-prefix=EFPU2 |
| |
| ;--- single.ll |
| ; single tests (identical for -mattr=+spe and -mattr=+efpu2) |
| |
| declare float @llvm.fabs.float(float) |
| define float @test_float_abs(float %a) #0 { |
| ; CHECK-LABEL: test_float_abs: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efsabs 3, 3 |
| ; CHECK-NEXT: blr |
| entry: |
| %0 = tail call float @llvm.fabs.float(float %a) |
| ret float %0 |
| } |
| |
| define float @test_fnabs(float %a) #0 { |
| ; CHECK-LABEL: test_fnabs: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efsnabs 3, 3 |
| ; CHECK-NEXT: blr |
| entry: |
| %0 = tail call float @llvm.fabs.float(float %a) |
| %sub = fsub float -0.000000e+00, %0 |
| ret float %sub |
| } |
| |
| define float @test_fdiv(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fdiv: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efsdiv 3, 3, 4 |
| ; CHECK-NEXT: blr |
| entry: |
| %v = fdiv float %a, %b |
| ret float %v |
| |
| } |
| |
| define float @test_fmul(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fmul: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efsmul 3, 3, 4 |
| ; CHECK-NEXT: blr |
| entry: |
| %v = fmul float %a, %b |
| ret float %v |
| } |
| |
| define float @test_fadd(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fadd: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efsadd 3, 3, 4 |
| ; CHECK-NEXT: blr |
| entry: |
| %v = fadd float %a, %b |
| ret float %v |
| } |
| |
| define float @test_fsub(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fsub: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efssub 3, 3, 4 |
| ; CHECK-NEXT: blr |
| entry: |
| %v = fsub float %a, %b |
| ret float %v |
| } |
| |
| define float @test_fneg(float %a) #0 { |
| ; CHECK-LABEL: test_fneg: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efsneg 3, 3 |
| ; CHECK-NEXT: blr |
| entry: |
| %v = fsub float -0.0, %a |
| ret float %v |
| } |
| |
| define i32 @test_fcmpgt(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpgt: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: stwu 1, -16(1) |
| ; CHECK-NEXT: efscmpgt 0, 3, 4 |
| ; CHECK-NEXT: ble 0, .LBB7_2 |
| ; CHECK-NEXT: # %bb.1: # %tr |
| ; CHECK-NEXT: li 3, 1 |
| ; CHECK-NEXT: b .LBB7_3 |
| ; CHECK-NEXT: .LBB7_2: # %fa |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: .LBB7_3: # %ret |
| ; CHECK-NEXT: stw 3, 12(1) |
| ; CHECK-NEXT: lwz 3, 12(1) |
| ; CHECK-NEXT: addi 1, 1, 16 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp ogt float %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i32 @test_fcmpugt(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpugt: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: stwu 1, -16(1) |
| ; CHECK-NEXT: efscmpeq 0, 4, 4 |
| ; CHECK-NEXT: bc 4, 1, .LBB8_4 |
| ; CHECK-NEXT: # %bb.1: # %entry |
| ; CHECK-NEXT: efscmpeq 0, 3, 3 |
| ; CHECK-NEXT: bc 4, 1, .LBB8_4 |
| ; CHECK-NEXT: # %bb.2: # %entry |
| ; CHECK-NEXT: efscmpgt 0, 3, 4 |
| ; CHECK-NEXT: bc 12, 1, .LBB8_4 |
| ; CHECK-NEXT: # %bb.3: # %fa |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: b .LBB8_5 |
| ; CHECK-NEXT: .LBB8_4: # %tr |
| ; CHECK-NEXT: li 3, 1 |
| ; CHECK-NEXT: .LBB8_5: # %ret |
| ; CHECK-NEXT: stw 3, 12(1) |
| ; CHECK-NEXT: lwz 3, 12(1) |
| ; CHECK-NEXT: addi 1, 1, 16 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp ugt float %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i32 @test_fcmple(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmple: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: stwu 1, -16(1) |
| ; CHECK-NEXT: efscmpeq 0, 3, 3 |
| ; CHECK-NEXT: bc 4, 1, .LBB9_4 |
| ; CHECK-NEXT: # %bb.1: # %entry |
| ; CHECK-NEXT: efscmpeq 0, 4, 4 |
| ; CHECK-NEXT: bc 4, 1, .LBB9_4 |
| ; CHECK-NEXT: # %bb.2: # %entry |
| ; CHECK-NEXT: efscmpgt 0, 3, 4 |
| ; CHECK-NEXT: bc 12, 1, .LBB9_4 |
| ; CHECK-NEXT: # %bb.3: # %tr |
| ; CHECK-NEXT: li 3, 1 |
| ; CHECK-NEXT: b .LBB9_5 |
| ; CHECK-NEXT: .LBB9_4: # %fa |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: .LBB9_5: # %ret |
| ; CHECK-NEXT: stw 3, 12(1) |
| ; CHECK-NEXT: lwz 3, 12(1) |
| ; CHECK-NEXT: addi 1, 1, 16 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp ole float %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i32 @test_fcmpule(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpule: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: stwu 1, -16(1) |
| ; CHECK-NEXT: efscmpgt 0, 3, 4 |
| ; CHECK-NEXT: bgt 0, .LBB10_2 |
| ; CHECK-NEXT: # %bb.1: # %tr |
| ; CHECK-NEXT: li 3, 1 |
| ; CHECK-NEXT: b .LBB10_3 |
| ; CHECK-NEXT: .LBB10_2: # %fa |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: .LBB10_3: # %ret |
| ; CHECK-NEXT: stw 3, 12(1) |
| ; CHECK-NEXT: lwz 3, 12(1) |
| ; CHECK-NEXT: addi 1, 1, 16 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp ule float %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| ; The type of comparison found in C's if (x == y) |
| define i32 @test_fcmpeq(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpeq: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: stwu 1, -16(1) |
| ; CHECK-NEXT: efscmpeq 0, 3, 4 |
| ; CHECK-NEXT: ble 0, .LBB11_2 |
| ; CHECK-NEXT: # %bb.1: # %tr |
| ; CHECK-NEXT: li 3, 1 |
| ; CHECK-NEXT: b .LBB11_3 |
| ; CHECK-NEXT: .LBB11_2: # %fa |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: .LBB11_3: # %ret |
| ; CHECK-NEXT: stw 3, 12(1) |
| ; CHECK-NEXT: lwz 3, 12(1) |
| ; CHECK-NEXT: addi 1, 1, 16 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp oeq float %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| ; (un)ordered tests are expanded to une and oeq so verify |
| define i1 @test_fcmpuno(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpuno: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efscmpeq 0, 3, 3 |
| ; CHECK-NEXT: efscmpeq 1, 4, 4 |
| ; CHECK-NEXT: li 5, 1 |
| ; CHECK-NEXT: crand 20, 5, 1 |
| ; CHECK-NEXT: bc 12, 20, .LBB12_2 |
| ; CHECK-NEXT: # %bb.1: # %entry |
| ; CHECK-NEXT: ori 3, 5, 0 |
| ; CHECK-NEXT: blr |
| ; CHECK-NEXT: .LBB12_2: # %entry |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = fcmp uno float %a, %b |
| ret i1 %r |
| } |
| |
| define i1 @test_fcmpord(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpord: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efscmpeq 0, 4, 4 |
| ; CHECK-NEXT: efscmpeq 1, 3, 3 |
| ; CHECK-NEXT: li 5, 1 |
| ; CHECK-NEXT: crnand 20, 5, 1 |
| ; CHECK-NEXT: bc 12, 20, .LBB13_2 |
| ; CHECK-NEXT: # %bb.1: # %entry |
| ; CHECK-NEXT: ori 3, 5, 0 |
| ; CHECK-NEXT: blr |
| ; CHECK-NEXT: .LBB13_2: # %entry |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = fcmp ord float %a, %b |
| ret i1 %r |
| } |
| |
| define i1 @test_fcmpueq(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpueq: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efscmpgt 0, 3, 4 |
| ; CHECK-NEXT: efscmplt 1, 3, 4 |
| ; CHECK-NEXT: li 5, 1 |
| ; CHECK-NEXT: cror 20, 5, 1 |
| ; CHECK-NEXT: bc 12, 20, .LBB14_2 |
| ; CHECK-NEXT: # %bb.1: # %entry |
| ; CHECK-NEXT: ori 3, 5, 0 |
| ; CHECK-NEXT: blr |
| ; CHECK-NEXT: .LBB14_2: # %entry |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = fcmp ueq float %a, %b |
| ret i1 %r |
| } |
| |
| define i1 @test_fcmpne(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpne: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efscmplt 0, 3, 4 |
| ; CHECK-NEXT: efscmpgt 1, 3, 4 |
| ; CHECK-NEXT: li 5, 1 |
| ; CHECK-NEXT: crnor 20, 5, 1 |
| ; CHECK-NEXT: bc 12, 20, .LBB15_2 |
| ; CHECK-NEXT: # %bb.1: # %entry |
| ; CHECK-NEXT: ori 3, 5, 0 |
| ; CHECK-NEXT: blr |
| ; CHECK-NEXT: .LBB15_2: # %entry |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = fcmp one float %a, %b |
| ret i1 %r |
| } |
| |
| define i32 @test_fcmpune(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpune: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: stwu 1, -16(1) |
| ; CHECK-NEXT: efscmpeq 0, 3, 4 |
| ; CHECK-NEXT: bgt 0, .LBB16_2 |
| ; CHECK-NEXT: # %bb.1: # %tr |
| ; CHECK-NEXT: li 3, 1 |
| ; CHECK-NEXT: b .LBB16_3 |
| ; CHECK-NEXT: .LBB16_2: # %fa |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: .LBB16_3: # %ret |
| ; CHECK-NEXT: stw 3, 12(1) |
| ; CHECK-NEXT: lwz 3, 12(1) |
| ; CHECK-NEXT: addi 1, 1, 16 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp une float %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i32 @test_fcmplt(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmplt: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: stwu 1, -16(1) |
| ; CHECK-NEXT: efscmplt 0, 3, 4 |
| ; CHECK-NEXT: ble 0, .LBB17_2 |
| ; CHECK-NEXT: # %bb.1: # %tr |
| ; CHECK-NEXT: li 3, 1 |
| ; CHECK-NEXT: b .LBB17_3 |
| ; CHECK-NEXT: .LBB17_2: # %fa |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: .LBB17_3: # %ret |
| ; CHECK-NEXT: stw 3, 12(1) |
| ; CHECK-NEXT: lwz 3, 12(1) |
| ; CHECK-NEXT: addi 1, 1, 16 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp olt float %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i1 @test_fcmpult(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpult: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: efscmpeq 0, 3, 3 |
| ; CHECK-NEXT: efscmpeq 1, 4, 4 |
| ; CHECK-NEXT: crnand 20, 5, 1 |
| ; CHECK-NEXT: efscmplt 0, 3, 4 |
| ; CHECK-NEXT: li 5, 1 |
| ; CHECK-NEXT: crnor 20, 1, 20 |
| ; CHECK-NEXT: bc 12, 20, .LBB18_2 |
| ; CHECK-NEXT: # %bb.1: # %entry |
| ; CHECK-NEXT: ori 3, 5, 0 |
| ; CHECK-NEXT: blr |
| ; CHECK-NEXT: .LBB18_2: # %entry |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = fcmp ult float %a, %b |
| ret i1 %r |
| } |
| |
| define i32 @test_fcmpge(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpge: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: stwu 1, -16(1) |
| ; CHECK-NEXT: efscmpeq 0, 3, 3 |
| ; CHECK-NEXT: bc 4, 1, .LBB19_4 |
| ; CHECK-NEXT: # %bb.1: # %entry |
| ; CHECK-NEXT: efscmpeq 0, 4, 4 |
| ; CHECK-NEXT: bc 4, 1, .LBB19_4 |
| ; CHECK-NEXT: # %bb.2: # %entry |
| ; CHECK-NEXT: efscmplt 0, 3, 4 |
| ; CHECK-NEXT: bc 12, 1, .LBB19_4 |
| ; CHECK-NEXT: # %bb.3: # %tr |
| ; CHECK-NEXT: li 3, 1 |
| ; CHECK-NEXT: b .LBB19_5 |
| ; CHECK-NEXT: .LBB19_4: # %fa |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: .LBB19_5: # %ret |
| ; CHECK-NEXT: stw 3, 12(1) |
| ; CHECK-NEXT: lwz 3, 12(1) |
| ; CHECK-NEXT: addi 1, 1, 16 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp oge float %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i32 @test_fcmpuge(float %a, float %b) #0 { |
| ; CHECK-LABEL: test_fcmpuge: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: stwu 1, -16(1) |
| ; CHECK-NEXT: efscmplt 0, 3, 4 |
| ; CHECK-NEXT: bgt 0, .LBB20_2 |
| ; CHECK-NEXT: # %bb.1: # %tr |
| ; CHECK-NEXT: li 3, 1 |
| ; CHECK-NEXT: b .LBB20_3 |
| ; CHECK-NEXT: .LBB20_2: # %fa |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: .LBB20_3: # %ret |
| ; CHECK-NEXT: stw 3, 12(1) |
| ; CHECK-NEXT: lwz 3, 12(1) |
| ; CHECK-NEXT: addi 1, 1, 16 |
| ; CHECK-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp uge float %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| |
| define i32 @test_ftoui(float %a) #0 { |
| ; CHECK-LABEL: test_ftoui: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: efsctuiz 3, 3 |
| ; CHECK-NEXT: blr |
| %v = fptoui float %a to i32 |
| ret i32 %v |
| } |
| |
| define i32 @test_ftosi(float %a) #0 { |
| ; CHECK-LABEL: test_ftosi: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: efsctsiz 3, 3 |
| ; CHECK-NEXT: blr |
| %v = fptosi float %a to i32 |
| ret i32 %v |
| } |
| |
| define float @test_ffromui(i32 %a) #0 { |
| ; CHECK-LABEL: test_ffromui: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: efscfui 3, 3 |
| ; CHECK-NEXT: blr |
| %v = uitofp i32 %a to float |
| ret float %v |
| } |
| |
| define float @test_ffromsi(i32 %a) #0 { |
| ; CHECK-LABEL: test_ffromsi: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: efscfsi 3, 3 |
| ; CHECK-NEXT: blr |
| %v = sitofp i32 %a to float |
| ret float %v |
| } |
| |
| define i32 @test_fasmconst(float %x) #0 { |
| ; CHECK-LABEL: test_fasmconst: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: stwu 1, -32(1) |
| ; CHECK-NEXT: stw 3, 20(1) |
| ; CHECK-NEXT: stw 3, 24(1) |
| ; CHECK-NEXT: lwz 3, 20(1) |
| ; CHECK-NEXT: #APP |
| ; CHECK-NEXT: efsctsi 3, 3 |
| ; CHECK-NEXT: #NO_APP |
| ; CHECK-NEXT: addi 1, 1, 32 |
| ; CHECK-NEXT: blr |
| entry: |
| %x.addr = alloca float, align 8 |
| store float %x, float* %x.addr, align 8 |
| %0 = load float, float* %x.addr, align 8 |
| %1 = call i32 asm sideeffect "efsctsi $0, $1", "=f,f"(float %0) |
| ret i32 %1 |
| ; Check that it's not loading a double |
| } |
| attributes #0 = { nounwind } |
| |
| ;--- double.ll |
| ; Double tests |
| ; results depend on -mattr=+spe or -mattr=+efpu2 |
| |
| define float @test_dtos(double %a) #0 { |
| ; SPE-LABEL: test_dtos: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efscfd 3, 3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dtos: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __truncdfsf2 |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v = fptrunc double %a to float |
| ret float %v |
| } |
| |
| define void @test_double_abs(double * %aa) #0 { |
| ; SPE-LABEL: test_double_abs: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evldd 4, 0(3) |
| ; SPE-NEXT: efdabs 4, 4 |
| ; SPE-NEXT: evstdd 4, 0(3) |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_double_abs: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: lwz 4, 0(3) |
| ; EFPU2-NEXT: clrlwi 4, 4, 1 |
| ; EFPU2-NEXT: stw 4, 0(3) |
| ; EFPU2-NEXT: blr |
| entry: |
| %0 = load double, double * %aa |
| %1 = tail call double @llvm.fabs.f64(double %0) #2 |
| store double %1, double * %aa |
| ret void |
| } |
| |
| ; Function Attrs: nounwind readnone |
| declare double @llvm.fabs.f64(double) #1 |
| |
| define void @test_dnabs(double * %aa) #0 { |
| ; SPE-LABEL: test_dnabs: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evldd 4, 0(3) |
| ; SPE-NEXT: efdnabs 4, 4 |
| ; SPE-NEXT: evstdd 4, 0(3) |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dnabs: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: lwz 4, 0(3) |
| ; EFPU2-NEXT: oris 4, 4, 32768 |
| ; EFPU2-NEXT: stw 4, 0(3) |
| ; EFPU2-NEXT: blr |
| entry: |
| %0 = load double, double * %aa |
| %1 = tail call double @llvm.fabs.f64(double %0) #2 |
| %sub = fsub double -0.000000e+00, %1 |
| store double %sub, double * %aa |
| ret void |
| } |
| |
| define double @test_ddiv(double %a, double %b) #0 { |
| ; SPE-LABEL: test_ddiv: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efddiv 4, 3, 5 |
| ; SPE-NEXT: evmergehi 3, 4, 4 |
| ; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_ddiv: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __divdf3 |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v = fdiv double %a, %b |
| ret double %v |
| |
| } |
| |
| define double @test_dmul(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dmul: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdmul 4, 3, 5 |
| ; SPE-NEXT: evmergehi 3, 4, 4 |
| ; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dmul: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __muldf3 |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v = fmul double %a, %b |
| ret double %v |
| } |
| |
| define double @test_dadd(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dadd: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdadd 4, 3, 5 |
| ; SPE-NEXT: evmergehi 3, 4, 4 |
| ; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dadd: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __adddf3 |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v = fadd double %a, %b |
| ret double %v |
| } |
| |
| define double @test_dsub(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dsub: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdsub 4, 3, 5 |
| ; SPE-NEXT: evmergehi 3, 4, 4 |
| ; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dsub: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __subdf3 |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v = fsub double %a, %b |
| ret double %v |
| } |
| |
| define double @test_dneg(double %a) #0 { |
| ; SPE-LABEL: test_dneg: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdneg 4, 3 |
| ; SPE-NEXT: evmergehi 3, 4, 4 |
| ; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dneg: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: xoris 3, 3, 32768 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v = fsub double -0.0, %a |
| ret double %v |
| } |
| |
| define double @test_stod(float %a) #0 { |
| ; SPE-LABEL: test_stod: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: efdcfs 4, 3 |
| ; SPE-NEXT: evmergehi 3, 4, 4 |
| ; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_stod: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __extendsfdf2 |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v = fpext float %a to double |
| ret double %v |
| } |
| |
| ; (un)ordered tests are expanded to une and oeq so verify |
| define i1 @test_dcmpuno(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpuno: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: li 7, 1 |
| ; SPE-NEXT: efdcmpeq 0, 3, 3 |
| ; SPE-NEXT: efdcmpeq 1, 5, 5 |
| ; SPE-NEXT: crand 20, 5, 1 |
| ; SPE-NEXT: bc 12, 20, .LBB9_2 |
| ; SPE-NEXT: # %bb.1: # %entry |
| ; SPE-NEXT: ori 3, 7, 0 |
| ; SPE-NEXT: blr |
| ; SPE-NEXT: .LBB9_2: # %entry |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpuno: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __unorddf2 |
| ; EFPU2-NEXT: cntlzw 3, 3 |
| ; EFPU2-NEXT: not 3, 3 |
| ; EFPU2-NEXT: rlwinm 3, 3, 27, 31, 31 |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = fcmp uno double %a, %b |
| ret i1 %r |
| } |
| |
| define i1 @test_dcmpord(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpord: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: evmergelo 4, 5, 6 |
| ; SPE-NEXT: li 7, 1 |
| ; SPE-NEXT: efdcmpeq 0, 4, 4 |
| ; SPE-NEXT: efdcmpeq 1, 3, 3 |
| ; SPE-NEXT: crnand 20, 5, 1 |
| ; SPE-NEXT: bc 12, 20, .LBB10_2 |
| ; SPE-NEXT: # %bb.1: # %entry |
| ; SPE-NEXT: ori 3, 7, 0 |
| ; SPE-NEXT: blr |
| ; SPE-NEXT: .LBB10_2: # %entry |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpord: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __unorddf2 |
| ; EFPU2-NEXT: cntlzw 3, 3 |
| ; EFPU2-NEXT: rlwinm 3, 3, 27, 31, 31 |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = fcmp ord double %a, %b |
| ret i1 %r |
| } |
| |
| define i32 @test_dcmpgt(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpgt: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: stwu 1, -16(1) |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdcmpgt 0, 3, 5 |
| ; SPE-NEXT: ble 0, .LBB11_2 |
| ; SPE-NEXT: # %bb.1: # %tr |
| ; SPE-NEXT: li 3, 1 |
| ; SPE-NEXT: b .LBB11_3 |
| ; SPE-NEXT: .LBB11_2: # %fa |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: .LBB11_3: # %ret |
| ; SPE-NEXT: stw 3, 12(1) |
| ; SPE-NEXT: lwz 3, 12(1) |
| ; SPE-NEXT: addi 1, 1, 16 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpgt: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __gtdf2 |
| ; EFPU2-NEXT: cmpwi 3, 1 |
| ; EFPU2-NEXT: blt 0, .LBB11_2 |
| ; EFPU2-NEXT: # %bb.1: # %tr |
| ; EFPU2-NEXT: li 3, 1 |
| ; EFPU2-NEXT: b .LBB11_3 |
| ; EFPU2-NEXT: .LBB11_2: # %fa |
| ; EFPU2-NEXT: li 3, 0 |
| ; EFPU2-NEXT: .LBB11_3: # %ret |
| ; EFPU2-NEXT: stw 3, 12(1) |
| ; EFPU2-NEXT: lwz 3, 12(1) |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp ogt double %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i32 @test_dcmpugt(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpugt: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: stwu 1, -16(1) |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: evmergelo 4, 5, 6 |
| ; SPE-NEXT: efdcmpeq 0, 4, 4 |
| ; SPE-NEXT: bc 4, 1, .LBB12_4 |
| ; SPE-NEXT: # %bb.1: # %entry |
| ; SPE-NEXT: efdcmpeq 0, 3, 3 |
| ; SPE-NEXT: bc 4, 1, .LBB12_4 |
| ; SPE-NEXT: # %bb.2: # %entry |
| ; SPE-NEXT: efdcmpgt 0, 3, 4 |
| ; SPE-NEXT: bc 12, 1, .LBB12_4 |
| ; SPE-NEXT: # %bb.3: # %fa |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: b .LBB12_5 |
| ; SPE-NEXT: .LBB12_4: # %tr |
| ; SPE-NEXT: li 3, 1 |
| ; SPE-NEXT: .LBB12_5: # %ret |
| ; SPE-NEXT: stw 3, 12(1) |
| ; SPE-NEXT: lwz 3, 12(1) |
| ; SPE-NEXT: addi 1, 1, 16 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpugt: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __ledf2 |
| ; EFPU2-NEXT: cmpwi 3, 1 |
| ; EFPU2-NEXT: blt 0, .LBB12_2 |
| ; EFPU2-NEXT: # %bb.1: # %tr |
| ; EFPU2-NEXT: li 3, 1 |
| ; EFPU2-NEXT: b .LBB12_3 |
| ; EFPU2-NEXT: .LBB12_2: # %fa |
| ; EFPU2-NEXT: li 3, 0 |
| ; EFPU2-NEXT: .LBB12_3: # %ret |
| ; EFPU2-NEXT: stw 3, 12(1) |
| ; EFPU2-NEXT: lwz 3, 12(1) |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp ugt double %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i32 @test_dcmple(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmple: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: stwu 1, -16(1) |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdcmpgt 0, 3, 5 |
| ; SPE-NEXT: bgt 0, .LBB13_2 |
| ; SPE-NEXT: # %bb.1: # %tr |
| ; SPE-NEXT: li 3, 1 |
| ; SPE-NEXT: b .LBB13_3 |
| ; SPE-NEXT: .LBB13_2: # %fa |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: .LBB13_3: # %ret |
| ; SPE-NEXT: stw 3, 12(1) |
| ; SPE-NEXT: lwz 3, 12(1) |
| ; SPE-NEXT: addi 1, 1, 16 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmple: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __gtdf2 |
| ; EFPU2-NEXT: cmpwi 3, 0 |
| ; EFPU2-NEXT: bgt 0, .LBB13_2 |
| ; EFPU2-NEXT: # %bb.1: # %tr |
| ; EFPU2-NEXT: li 3, 1 |
| ; EFPU2-NEXT: b .LBB13_3 |
| ; EFPU2-NEXT: .LBB13_2: # %fa |
| ; EFPU2-NEXT: li 3, 0 |
| ; EFPU2-NEXT: .LBB13_3: # %ret |
| ; EFPU2-NEXT: stw 3, 12(1) |
| ; EFPU2-NEXT: lwz 3, 12(1) |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp ule double %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i32 @test_dcmpule(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpule: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: stwu 1, -16(1) |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdcmpgt 0, 3, 5 |
| ; SPE-NEXT: bgt 0, .LBB14_2 |
| ; SPE-NEXT: # %bb.1: # %tr |
| ; SPE-NEXT: li 3, 1 |
| ; SPE-NEXT: b .LBB14_3 |
| ; SPE-NEXT: .LBB14_2: # %fa |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: .LBB14_3: # %ret |
| ; SPE-NEXT: stw 3, 12(1) |
| ; SPE-NEXT: lwz 3, 12(1) |
| ; SPE-NEXT: addi 1, 1, 16 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpule: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __gtdf2 |
| ; EFPU2-NEXT: cmpwi 3, 0 |
| ; EFPU2-NEXT: bgt 0, .LBB14_2 |
| ; EFPU2-NEXT: # %bb.1: # %tr |
| ; EFPU2-NEXT: li 3, 1 |
| ; EFPU2-NEXT: b .LBB14_3 |
| ; EFPU2-NEXT: .LBB14_2: # %fa |
| ; EFPU2-NEXT: li 3, 0 |
| ; EFPU2-NEXT: .LBB14_3: # %ret |
| ; EFPU2-NEXT: stw 3, 12(1) |
| ; EFPU2-NEXT: lwz 3, 12(1) |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp ule double %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| ; The type of comparison found in C's if (x == y) |
| define i32 @test_dcmpeq(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpeq: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: stwu 1, -16(1) |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdcmpeq 0, 3, 5 |
| ; SPE-NEXT: ble 0, .LBB15_2 |
| ; SPE-NEXT: # %bb.1: # %tr |
| ; SPE-NEXT: li 3, 1 |
| ; SPE-NEXT: b .LBB15_3 |
| ; SPE-NEXT: .LBB15_2: # %fa |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: .LBB15_3: # %ret |
| ; SPE-NEXT: stw 3, 12(1) |
| ; SPE-NEXT: lwz 3, 12(1) |
| ; SPE-NEXT: addi 1, 1, 16 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpeq: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __nedf2 |
| ; EFPU2-NEXT: cmplwi 3, 0 |
| ; EFPU2-NEXT: bne 0, .LBB15_2 |
| ; EFPU2-NEXT: # %bb.1: # %tr |
| ; EFPU2-NEXT: li 3, 1 |
| ; EFPU2-NEXT: b .LBB15_3 |
| ; EFPU2-NEXT: .LBB15_2: # %fa |
| ; EFPU2-NEXT: li 3, 0 |
| ; EFPU2-NEXT: .LBB15_3: # %ret |
| ; EFPU2-NEXT: stw 3, 12(1) |
| ; EFPU2-NEXT: lwz 3, 12(1) |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp oeq double %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i32 @test_dcmpueq(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpueq: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: stwu 1, -16(1) |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdcmplt 0, 3, 5 |
| ; SPE-NEXT: bc 12, 1, .LBB16_3 |
| ; SPE-NEXT: # %bb.1: # %entry |
| ; SPE-NEXT: efdcmpgt 0, 3, 5 |
| ; SPE-NEXT: bc 12, 1, .LBB16_3 |
| ; SPE-NEXT: # %bb.2: # %tr |
| ; SPE-NEXT: li 3, 1 |
| ; SPE-NEXT: b .LBB16_4 |
| ; SPE-NEXT: .LBB16_3: # %fa |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: .LBB16_4: # %ret |
| ; SPE-NEXT: stw 3, 12(1) |
| ; SPE-NEXT: lwz 3, 12(1) |
| ; SPE-NEXT: addi 1, 1, 16 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpueq: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -96(1) |
| ; EFPU2-NEXT: mfcr 12 |
| ; EFPU2-NEXT: stw 27, 76(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 28, 80(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 29, 84(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 30, 88(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 12, 72(1) |
| ; EFPU2-NEXT: evstdd 27, 24(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: mr 27, 3 |
| ; EFPU2-NEXT: evstdd 28, 32(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: mr 28, 4 |
| ; EFPU2-NEXT: evstdd 29, 40(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: mr 29, 5 |
| ; EFPU2-NEXT: evstdd 30, 48(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: mr 30, 6 |
| ; EFPU2-NEXT: bl __eqdf2 |
| ; EFPU2-NEXT: cmpwi 2, 3, 0 |
| ; EFPU2-NEXT: mr 3, 27 |
| ; EFPU2-NEXT: mr 4, 28 |
| ; EFPU2-NEXT: mr 5, 29 |
| ; EFPU2-NEXT: mr 6, 30 |
| ; EFPU2-NEXT: bl __unorddf2 |
| ; EFPU2-NEXT: bc 12, 10, .LBB16_3 |
| ; EFPU2-NEXT: # %bb.1: # %entry |
| ; EFPU2-NEXT: cmpwi 3, 0 |
| ; EFPU2-NEXT: bc 4, 2, .LBB16_3 |
| ; EFPU2-NEXT: # %bb.2: # %fa |
| ; EFPU2-NEXT: li 3, 0 |
| ; EFPU2-NEXT: b .LBB16_4 |
| ; EFPU2-NEXT: .LBB16_3: # %tr |
| ; EFPU2-NEXT: li 3, 1 |
| ; EFPU2-NEXT: .LBB16_4: # %ret |
| ; EFPU2-NEXT: stw 3, 20(1) |
| ; EFPU2-NEXT: lwz 3, 20(1) |
| ; EFPU2-NEXT: evldd 30, 48(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: evldd 29, 40(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: evldd 28, 32(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: lwz 12, 72(1) |
| ; EFPU2-NEXT: evldd 27, 24(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: mtcrf 32, 12 # cr2 |
| ; EFPU2-NEXT: lwz 30, 88(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 29, 84(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 28, 80(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 27, 76(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 0, 100(1) |
| ; EFPU2-NEXT: addi 1, 1, 96 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp ueq double %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i1 @test_dcmpne(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpne: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: li 7, 1 |
| ; SPE-NEXT: efdcmplt 0, 3, 5 |
| ; SPE-NEXT: efdcmpgt 1, 3, 5 |
| ; SPE-NEXT: crnor 20, 5, 1 |
| ; SPE-NEXT: bc 12, 20, .LBB17_2 |
| ; SPE-NEXT: # %bb.1: # %entry |
| ; SPE-NEXT: ori 3, 7, 0 |
| ; SPE-NEXT: blr |
| ; SPE-NEXT: .LBB17_2: # %entry |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpne: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -96(1) |
| ; EFPU2-NEXT: mfcr 12 |
| ; EFPU2-NEXT: stw 27, 76(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 28, 80(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 29, 84(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 30, 88(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 12, 72(1) |
| ; EFPU2-NEXT: evstdd 27, 24(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: mr 27, 3 |
| ; EFPU2-NEXT: evstdd 28, 32(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: mr 28, 4 |
| ; EFPU2-NEXT: evstdd 29, 40(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: mr 29, 5 |
| ; EFPU2-NEXT: evstdd 30, 48(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: mr 30, 6 |
| ; EFPU2-NEXT: bl __unorddf2 |
| ; EFPU2-NEXT: cmpwi 2, 3, 0 |
| ; EFPU2-NEXT: mr 3, 27 |
| ; EFPU2-NEXT: mr 4, 28 |
| ; EFPU2-NEXT: mr 5, 29 |
| ; EFPU2-NEXT: mr 6, 30 |
| ; EFPU2-NEXT: bl __eqdf2 |
| ; EFPU2-NEXT: evldd 30, 48(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: cmpwi 3, 0 |
| ; EFPU2-NEXT: evldd 29, 40(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: li 4, 1 |
| ; EFPU2-NEXT: evldd 28, 32(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: crorc 20, 2, 10 |
| ; EFPU2-NEXT: lwz 12, 72(1) |
| ; EFPU2-NEXT: bc 12, 20, .LBB17_2 |
| ; EFPU2-NEXT: # %bb.1: # %entry |
| ; EFPU2-NEXT: ori 3, 4, 0 |
| ; EFPU2-NEXT: b .LBB17_3 |
| ; EFPU2-NEXT: .LBB17_2: # %entry |
| ; EFPU2-NEXT: li 3, 0 |
| ; EFPU2-NEXT: .LBB17_3: # %entry |
| ; EFPU2-NEXT: evldd 27, 24(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: mtcrf 32, 12 # cr2 |
| ; EFPU2-NEXT: lwz 30, 88(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 29, 84(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 28, 80(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 27, 76(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 0, 100(1) |
| ; EFPU2-NEXT: addi 1, 1, 96 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = fcmp one double %a, %b |
| ret i1 %r |
| } |
| |
| define i32 @test_dcmpune(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpune: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: stwu 1, -16(1) |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdcmpeq 0, 3, 5 |
| ; SPE-NEXT: bgt 0, .LBB18_2 |
| ; SPE-NEXT: # %bb.1: # %tr |
| ; SPE-NEXT: li 3, 1 |
| ; SPE-NEXT: b .LBB18_3 |
| ; SPE-NEXT: .LBB18_2: # %fa |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: .LBB18_3: # %ret |
| ; SPE-NEXT: stw 3, 12(1) |
| ; SPE-NEXT: lwz 3, 12(1) |
| ; SPE-NEXT: addi 1, 1, 16 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpune: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __eqdf2 |
| ; EFPU2-NEXT: cmplwi 3, 0 |
| ; EFPU2-NEXT: beq 0, .LBB18_2 |
| ; EFPU2-NEXT: # %bb.1: # %tr |
| ; EFPU2-NEXT: li 3, 1 |
| ; EFPU2-NEXT: b .LBB18_3 |
| ; EFPU2-NEXT: .LBB18_2: # %fa |
| ; EFPU2-NEXT: li 3, 0 |
| ; EFPU2-NEXT: .LBB18_3: # %ret |
| ; EFPU2-NEXT: stw 3, 12(1) |
| ; EFPU2-NEXT: lwz 3, 12(1) |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp une double %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i32 @test_dcmplt(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmplt: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: stwu 1, -16(1) |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdcmplt 0, 3, 5 |
| ; SPE-NEXT: ble 0, .LBB19_2 |
| ; SPE-NEXT: # %bb.1: # %tr |
| ; SPE-NEXT: li 3, 1 |
| ; SPE-NEXT: b .LBB19_3 |
| ; SPE-NEXT: .LBB19_2: # %fa |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: .LBB19_3: # %ret |
| ; SPE-NEXT: stw 3, 12(1) |
| ; SPE-NEXT: lwz 3, 12(1) |
| ; SPE-NEXT: addi 1, 1, 16 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmplt: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __ltdf2 |
| ; EFPU2-NEXT: cmpwi 3, -1 |
| ; EFPU2-NEXT: bgt 0, .LBB19_2 |
| ; EFPU2-NEXT: # %bb.1: # %tr |
| ; EFPU2-NEXT: li 3, 1 |
| ; EFPU2-NEXT: b .LBB19_3 |
| ; EFPU2-NEXT: .LBB19_2: # %fa |
| ; EFPU2-NEXT: li 3, 0 |
| ; EFPU2-NEXT: .LBB19_3: # %ret |
| ; EFPU2-NEXT: stw 3, 12(1) |
| ; EFPU2-NEXT: lwz 3, 12(1) |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp olt double %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i32 @test_dcmpult(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpult: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: stwu 1, -16(1) |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: evmergelo 4, 5, 6 |
| ; SPE-NEXT: efdcmpeq 0, 4, 4 |
| ; SPE-NEXT: bc 4, 1, .LBB20_4 |
| ; SPE-NEXT: # %bb.1: # %entry |
| ; SPE-NEXT: efdcmpeq 0, 3, 3 |
| ; SPE-NEXT: bc 4, 1, .LBB20_4 |
| ; SPE-NEXT: # %bb.2: # %entry |
| ; SPE-NEXT: efdcmplt 0, 3, 4 |
| ; SPE-NEXT: bc 12, 1, .LBB20_4 |
| ; SPE-NEXT: # %bb.3: # %fa |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: b .LBB20_5 |
| ; SPE-NEXT: .LBB20_4: # %tr |
| ; SPE-NEXT: li 3, 1 |
| ; SPE-NEXT: .LBB20_5: # %ret |
| ; SPE-NEXT: stw 3, 12(1) |
| ; SPE-NEXT: lwz 3, 12(1) |
| ; SPE-NEXT: addi 1, 1, 16 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpult: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __gedf2 |
| ; EFPU2-NEXT: cmpwi 3, -1 |
| ; EFPU2-NEXT: bgt 0, .LBB20_2 |
| ; EFPU2-NEXT: # %bb.1: # %tr |
| ; EFPU2-NEXT: li 3, 1 |
| ; EFPU2-NEXT: b .LBB20_3 |
| ; EFPU2-NEXT: .LBB20_2: # %fa |
| ; EFPU2-NEXT: li 3, 0 |
| ; EFPU2-NEXT: .LBB20_3: # %ret |
| ; EFPU2-NEXT: stw 3, 12(1) |
| ; EFPU2-NEXT: lwz 3, 12(1) |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp ult double %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define i1 @test_dcmpge(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpge: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: evmergelo 4, 5, 6 |
| ; SPE-NEXT: li 7, 1 |
| ; SPE-NEXT: efdcmpeq 0, 4, 4 |
| ; SPE-NEXT: efdcmpeq 1, 3, 3 |
| ; SPE-NEXT: efdcmplt 5, 3, 4 |
| ; SPE-NEXT: crand 24, 5, 1 |
| ; SPE-NEXT: crorc 20, 21, 24 |
| ; SPE-NEXT: bc 12, 20, .LBB21_2 |
| ; SPE-NEXT: # %bb.1: # %entry |
| ; SPE-NEXT: ori 3, 7, 0 |
| ; SPE-NEXT: blr |
| ; SPE-NEXT: .LBB21_2: # %entry |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpge: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __gedf2 |
| ; EFPU2-NEXT: not 3, 3 |
| ; EFPU2-NEXT: srwi 3, 3, 31 |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = fcmp oge double %a, %b |
| ret i1 %r |
| } |
| |
| define i32 @test_dcmpuge(double %a, double %b) #0 { |
| ; SPE-LABEL: test_dcmpuge: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: stwu 1, -16(1) |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdcmplt 0, 3, 5 |
| ; SPE-NEXT: bgt 0, .LBB22_2 |
| ; SPE-NEXT: # %bb.1: # %tr |
| ; SPE-NEXT: li 3, 1 |
| ; SPE-NEXT: b .LBB22_3 |
| ; SPE-NEXT: .LBB22_2: # %fa |
| ; SPE-NEXT: li 3, 0 |
| ; SPE-NEXT: .LBB22_3: # %ret |
| ; SPE-NEXT: stw 3, 12(1) |
| ; SPE-NEXT: lwz 3, 12(1) |
| ; SPE-NEXT: addi 1, 1, 16 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dcmpuge: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __ltdf2 |
| ; EFPU2-NEXT: cmpwi 3, 0 |
| ; EFPU2-NEXT: blt 0, .LBB22_2 |
| ; EFPU2-NEXT: # %bb.1: # %tr |
| ; EFPU2-NEXT: li 3, 1 |
| ; EFPU2-NEXT: b .LBB22_3 |
| ; EFPU2-NEXT: .LBB22_2: # %fa |
| ; EFPU2-NEXT: li 3, 0 |
| ; EFPU2-NEXT: .LBB22_3: # %ret |
| ; EFPU2-NEXT: stw 3, 12(1) |
| ; EFPU2-NEXT: lwz 3, 12(1) |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = alloca i32, align 4 |
| %c = fcmp uge double %a, %b |
| br i1 %c, label %tr, label %fa |
| tr: |
| store i32 1, i32* %r, align 4 |
| br label %ret |
| fa: |
| store i32 0, i32* %r, align 4 |
| br label %ret |
| ret: |
| %0 = load i32, i32* %r, align 4 |
| ret i32 %0 |
| } |
| |
| define double @test_dselect(double %a, double %b, i1 %c) #0 { |
| ; SPE-LABEL: test_dselect: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: andi. 7, 7, 1 |
| ; SPE-NEXT: evmergelo 5, 5, 6 |
| ; SPE-NEXT: evmergelo 4, 3, 4 |
| ; SPE-NEXT: bc 12, 1, .LBB23_2 |
| ; SPE-NEXT: # %bb.1: # %entry |
| ; SPE-NEXT: evor 4, 5, 5 |
| ; SPE-NEXT: .LBB23_2: # %entry |
| ; SPE-NEXT: evmergehi 3, 4, 4 |
| ; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dselect: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: andi. 7, 7, 1 |
| ; EFPU2-NEXT: bclr 12, 1, 0 |
| ; EFPU2-NEXT: # %bb.1: # %entry |
| ; EFPU2-NEXT: ori 3, 5, 0 |
| ; EFPU2-NEXT: ori 4, 6, 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %r = select i1 %c, double %a, double %b |
| ret double %r |
| } |
| |
| define i32 @test_dtoui(double %a) #0 { |
| ; SPE-LABEL: test_dtoui: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdctuiz 3, 3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dtoui: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __fixunsdfsi |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v = fptoui double %a to i32 |
| ret i32 %v |
| } |
| |
| define i32 @test_dtosi(double %a) #0 { |
| ; SPE-LABEL: test_dtosi: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: efdctsiz 3, 3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dtosi: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __fixdfsi |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v = fptosi double %a to i32 |
| ret i32 %v |
| } |
| |
| define double @test_dfromui(i32 %a) #0 { |
| ; SPE-LABEL: test_dfromui: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: efdcfui 4, 3 |
| ; SPE-NEXT: evmergehi 3, 4, 4 |
| ; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dfromui: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __floatunsidf |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v = uitofp i32 %a to double |
| ret double %v |
| } |
| |
| define double @test_dfromsi(i32 %a) #0 { |
| ; SPE-LABEL: test_dfromsi: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: efdcfsi 4, 3 |
| ; SPE-NEXT: evmergehi 3, 4, 4 |
| ; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_dfromsi: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -16(1) |
| ; EFPU2-NEXT: bl __floatsidf |
| ; EFPU2-NEXT: lwz 0, 20(1) |
| ; EFPU2-NEXT: addi 1, 1, 16 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v = sitofp i32 %a to double |
| ret double %v |
| } |
| |
| declare double @test_spill_spe_regs(double, double); |
| define dso_local void @test_func2() #0 { |
| ; SPE-LABEL: test_func2: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_func2: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: blr |
| entry: |
| ret void |
| } |
| |
| declare void @test_memset(i8* nocapture writeonly, i8, i32, i1) |
| @global_var1 = global i32 0, align 4 |
| define double @test_spill(double %a, i32 %a1, i64 %a2, i8 * %a3, i32 *%a4, i32* %a5) #0 { |
| ; SPE-LABEL: test_spill: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: mflr 0 |
| ; SPE-NEXT: stw 0, 4(1) |
| ; SPE-NEXT: stwu 1, -352(1) |
| ; SPE-NEXT: li 5, 256 |
| ; SPE-NEXT: evstddx 30, 1, 5 # 8-byte Folded Spill |
| ; SPE-NEXT: li 5, 264 |
| ; SPE-NEXT: evstddx 31, 1, 5 # 8-byte Folded Spill |
| ; SPE-NEXT: li 5, .LCPI29_0@l |
| ; SPE-NEXT: lis 6, .LCPI29_0@ha |
| ; SPE-NEXT: evlddx 5, 6, 5 |
| ; SPE-NEXT: stw 14, 280(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 15, 284(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 16, 288(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 17, 292(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 18, 296(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 19, 300(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 20, 304(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 21, 308(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 22, 312(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 23, 316(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 24, 320(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 25, 324(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 26, 328(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 27, 332(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 28, 336(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 29, 340(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 30, 344(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 31, 348(1) # 4-byte Folded Spill |
| ; SPE-NEXT: evstdd 14, 128(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 15, 136(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 16, 144(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 17, 152(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 18, 160(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 19, 168(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 20, 176(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 21, 184(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 22, 192(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 23, 200(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 24, 208(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 25, 216(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 26, 224(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 27, 232(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 28, 240(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 29, 248(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: lwz 4, 360(1) |
| ; SPE-NEXT: efdadd 3, 3, 3 |
| ; SPE-NEXT: efdadd 3, 3, 5 |
| ; SPE-NEXT: evstdd 3, 24(1) # 8-byte Folded Spill |
| ; SPE-NEXT: stw 4, 20(1) # 4-byte Folded Spill |
| ; SPE-NEXT: #APP |
| ; SPE-NEXT: #NO_APP |
| ; SPE-NEXT: addi 3, 1, 76 |
| ; SPE-NEXT: li 4, 0 |
| ; SPE-NEXT: li 5, 24 |
| ; SPE-NEXT: li 6, 1 |
| ; SPE-NEXT: li 30, 0 |
| ; SPE-NEXT: bl test_memset |
| ; SPE-NEXT: lwz 3, 20(1) # 4-byte Folded Reload |
| ; SPE-NEXT: stw 30, 0(3) |
| ; SPE-NEXT: bl test_func2 |
| ; SPE-NEXT: addi 3, 1, 32 |
| ; SPE-NEXT: li 4, 0 |
| ; SPE-NEXT: li 5, 20 |
| ; SPE-NEXT: li 6, 1 |
| ; SPE-NEXT: bl test_memset |
| ; SPE-NEXT: evldd 4, 24(1) # 8-byte Folded Reload |
| ; SPE-NEXT: li 5, 264 |
| ; SPE-NEXT: evmergehi 3, 4, 4 |
| ; SPE-NEXT: evlddx 31, 1, 5 # 8-byte Folded Reload |
| ; SPE-NEXT: li 5, 256 |
| ; SPE-NEXT: evlddx 30, 1, 5 # 8-byte Folded Reload |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: # kill: def $r4 killed $r4 killed $s4 |
| ; SPE-NEXT: evldd 29, 248(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 28, 240(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 27, 232(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 26, 224(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 25, 216(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 24, 208(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 23, 200(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 22, 192(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 21, 184(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 20, 176(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 19, 168(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 18, 160(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 17, 152(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 16, 144(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 15, 136(1) # 8-byte Folded Reload |
| ; SPE-NEXT: evldd 14, 128(1) # 8-byte Folded Reload |
| ; SPE-NEXT: lwz 31, 348(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 30, 344(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 29, 340(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 28, 336(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 27, 332(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 26, 328(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 25, 324(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 24, 320(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 23, 316(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 22, 312(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 21, 308(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 20, 304(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 19, 300(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 18, 296(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 17, 292(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 16, 288(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 15, 284(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 14, 280(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 0, 356(1) |
| ; SPE-NEXT: addi 1, 1, 352 |
| ; SPE-NEXT: mtlr 0 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_spill: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -176(1) |
| ; EFPU2-NEXT: mr 5, 3 |
| ; EFPU2-NEXT: mr 6, 4 |
| ; EFPU2-NEXT: stw 27, 156(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 28, 160(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 29, 164(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 30, 168(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: evstdd 27, 104(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: evstdd 28, 112(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: evstdd 29, 120(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: evstdd 30, 128(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: lwz 28, 184(1) |
| ; EFPU2-NEXT: bl __adddf3 |
| ; EFPU2-NEXT: lis 5, 16393 |
| ; EFPU2-NEXT: lis 6, -4069 |
| ; EFPU2-NEXT: ori 5, 5, 8697 |
| ; EFPU2-NEXT: ori 6, 6, 34414 |
| ; EFPU2-NEXT: #APP |
| ; EFPU2-NEXT: #NO_APP |
| ; EFPU2-NEXT: bl __adddf3 |
| ; EFPU2-NEXT: mr 30, 3 |
| ; EFPU2-NEXT: mr 29, 4 |
| ; EFPU2-NEXT: addi 3, 1, 52 |
| ; EFPU2-NEXT: li 4, 0 |
| ; EFPU2-NEXT: li 5, 24 |
| ; EFPU2-NEXT: li 6, 1 |
| ; EFPU2-NEXT: li 27, 0 |
| ; EFPU2-NEXT: bl test_memset |
| ; EFPU2-NEXT: stw 27, 0(28) |
| ; EFPU2-NEXT: bl test_func2 |
| ; EFPU2-NEXT: addi 3, 1, 8 |
| ; EFPU2-NEXT: li 4, 0 |
| ; EFPU2-NEXT: li 5, 20 |
| ; EFPU2-NEXT: li 6, 1 |
| ; EFPU2-NEXT: bl test_memset |
| ; EFPU2-NEXT: mr 3, 30 |
| ; EFPU2-NEXT: mr 4, 29 |
| ; EFPU2-NEXT: evldd 30, 128(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: evldd 29, 120(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: evldd 28, 112(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: evldd 27, 104(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: lwz 30, 168(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 29, 164(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 28, 160(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 27, 156(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 0, 180(1) |
| ; EFPU2-NEXT: addi 1, 1, 176 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %v1 = alloca [13 x i32], align 4 |
| %v2 = alloca [11 x i32], align 4 |
| %0 = fadd double %a, %a |
| call void asm sideeffect "","~{s0},~{s3},~{s4},~{s5},~{s6},~{s7},~{s8},~{s9},~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},~{s16},~{s17},~{s18},~{s19},~{s20},~{s21},~{s22},~{s23},~{s24},~{s25},~{s26},~{s27},~{s28},~{s29},~{s30},~{s31}"() nounwind |
| %1 = fadd double %0, 3.14159 |
| %2 = bitcast [13 x i32]* %v1 to i8* |
| call void @test_memset(i8* align 4 %2, i8 0, i32 24, i1 true) |
| store i32 0, i32* %a5, align 4 |
| call void @test_func2() |
| %3 = bitcast [11 x i32]* %v2 to i8* |
| call void @test_memset(i8* align 4 %3, i8 0, i32 20, i1 true) |
| br label %return |
| |
| return: |
| ret double %1 |
| |
| } |
| |
| define dso_local float @test_fma(i32 %d) local_unnamed_addr #0 { |
| ; SPE-LABEL: test_fma: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: mflr 0 |
| ; SPE-NEXT: stw 0, 4(1) |
| ; SPE-NEXT: stwu 1, -48(1) |
| ; SPE-NEXT: cmpwi 3, 1 |
| ; SPE-NEXT: stw 29, 36(1) # 4-byte Folded Spill |
| ; SPE-NEXT: stw 30, 40(1) # 4-byte Folded Spill |
| ; SPE-NEXT: evstdd 29, 8(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 30, 16(1) # 8-byte Folded Spill |
| ; SPE-NEXT: blt 0, .LBB30_3 |
| ; SPE-NEXT: # %bb.1: # %for.body.preheader |
| ; SPE-NEXT: mr 30, 3 |
| ; SPE-NEXT: li 29, 0 |
| ; SPE-NEXT: # implicit-def: $r5 |
| ; SPE-NEXT: .LBB30_2: # %for.body |
| ; SPE-NEXT: # |
| ; SPE-NEXT: efscfsi 3, 29 |
| ; SPE-NEXT: mr 4, 3 |
| ; SPE-NEXT: bl fmaf |
| ; SPE-NEXT: addi 29, 29, 1 |
| ; SPE-NEXT: cmplw 30, 29 |
| ; SPE-NEXT: mr 5, 3 |
| ; SPE-NEXT: bne 0, .LBB30_2 |
| ; SPE-NEXT: b .LBB30_4 |
| ; SPE-NEXT: .LBB30_3: |
| ; SPE-NEXT: # implicit-def: $r5 |
| ; SPE-NEXT: .LBB30_4: # %for.cond.cleanup |
| ; SPE-NEXT: evldd 30, 16(1) # 8-byte Folded Reload |
| ; SPE-NEXT: mr 3, 5 |
| ; SPE-NEXT: evldd 29, 8(1) # 8-byte Folded Reload |
| ; SPE-NEXT: lwz 30, 40(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 29, 36(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 0, 52(1) |
| ; SPE-NEXT: addi 1, 1, 48 |
| ; SPE-NEXT: mtlr 0 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: test_fma: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -48(1) |
| ; EFPU2-NEXT: cmpwi 3, 1 |
| ; EFPU2-NEXT: stw 29, 36(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 30, 40(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: evstdd 29, 8(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: evstdd 30, 16(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: blt 0, .LBB30_3 |
| ; EFPU2-NEXT: # %bb.1: # %for.body.preheader |
| ; EFPU2-NEXT: mr 30, 3 |
| ; EFPU2-NEXT: li 29, 0 |
| ; EFPU2-NEXT: # implicit-def: $r5 |
| ; EFPU2-NEXT: .LBB30_2: # %for.body |
| ; EFPU2-NEXT: # |
| ; EFPU2-NEXT: efscfsi 3, 29 |
| ; EFPU2-NEXT: mr 4, 3 |
| ; EFPU2-NEXT: bl fmaf |
| ; EFPU2-NEXT: addi 29, 29, 1 |
| ; EFPU2-NEXT: cmplw 30, 29 |
| ; EFPU2-NEXT: mr 5, 3 |
| ; EFPU2-NEXT: bne 0, .LBB30_2 |
| ; EFPU2-NEXT: b .LBB30_4 |
| ; EFPU2-NEXT: .LBB30_3: |
| ; EFPU2-NEXT: # implicit-def: $r5 |
| ; EFPU2-NEXT: .LBB30_4: # %for.cond.cleanup |
| ; EFPU2-NEXT: evldd 30, 16(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: mr 3, 5 |
| ; EFPU2-NEXT: evldd 29, 8(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: lwz 30, 40(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 29, 36(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 0, 52(1) |
| ; EFPU2-NEXT: addi 1, 1, 48 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %cmp8 = icmp sgt i32 %d, 0 |
| br i1 %cmp8, label %for.body, label %for.cond.cleanup |
| |
| for.cond.cleanup: ; preds = %for.body, %entry |
| %e.0.lcssa = phi float [ undef, %entry ], [ %0, %for.body ] |
| ret float %e.0.lcssa |
| |
| for.body: ; preds = %for.body, %entry |
| %f.010 = phi i32 [ %inc, %for.body ], [ 0, %entry ] |
| %e.09 = phi float [ %0, %for.body ], [ undef, %entry ] |
| %conv = sitofp i32 %f.010 to float |
| %0 = tail call float @llvm.fma.f32(float %conv, float %conv, float %e.09) |
| %inc = add nuw nsw i32 %f.010, 1 |
| %exitcond = icmp eq i32 %inc, %d |
| br i1 %exitcond, label %for.cond.cleanup, label %for.body |
| } |
| |
| ; Function Attrs: nounwind readnone speculatable willreturn |
| declare float @llvm.fma.f32(float, float, float) #1 |
| |
| attributes #1 = { nounwind readnone speculatable willreturn } |
| |
| %struct.a = type { float, float } |
| |
| declare i32 @foo(double) |
| |
| define void @d(%struct.a* %e, %struct.a* %f) #0 { |
| ; SPE-LABEL: d: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: mflr 0 |
| ; SPE-NEXT: stw 0, 4(1) |
| ; SPE-NEXT: stwu 1, -64(1) |
| ; SPE-NEXT: lwz 4, 0(4) |
| ; SPE-NEXT: lwz 3, 0(3) |
| ; SPE-NEXT: stw 29, 52(1) # 4-byte Folded Spill |
| ; SPE-NEXT: evstdd 29, 24(1) # 8-byte Folded Spill |
| ; SPE-NEXT: efdcfs 29, 4 |
| ; SPE-NEXT: stw 28, 48(1) # 4-byte Folded Spill |
| ; SPE-NEXT: mr 4, 29 |
| ; SPE-NEXT: stw 30, 56(1) # 4-byte Folded Spill |
| ; SPE-NEXT: evstdd 28, 16(1) # 8-byte Folded Spill |
| ; SPE-NEXT: evstdd 30, 32(1) # 8-byte Folded Spill |
| ; SPE-NEXT: efdcfs 30, 3 |
| ; SPE-NEXT: evmergehi 3, 29, 29 |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: bl foo |
| ; SPE-NEXT: mr 28, 3 |
| ; SPE-NEXT: evmergehi 3, 30, 30 |
| ; SPE-NEXT: mr 4, 30 |
| ; SPE-NEXT: # kill: def $r3 killed $r3 killed $s3 |
| ; SPE-NEXT: bl foo |
| ; SPE-NEXT: efdcfsi 3, 28 |
| ; SPE-NEXT: evldd 30, 32(1) # 8-byte Folded Reload |
| ; SPE-NEXT: efdmul 3, 29, 3 |
| ; SPE-NEXT: efscfd 3, 3 |
| ; SPE-NEXT: evldd 29, 24(1) # 8-byte Folded Reload |
| ; SPE-NEXT: stw 3, 0(3) |
| ; SPE-NEXT: evldd 28, 16(1) # 8-byte Folded Reload |
| ; SPE-NEXT: lwz 30, 56(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 29, 52(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 28, 48(1) # 4-byte Folded Reload |
| ; SPE-NEXT: lwz 0, 68(1) |
| ; SPE-NEXT: addi 1, 1, 64 |
| ; SPE-NEXT: mtlr 0 |
| ; SPE-NEXT: blr |
| ; |
| ; EFPU2-LABEL: d: |
| ; EFPU2: # %bb.0: # %entry |
| ; EFPU2-NEXT: mflr 0 |
| ; EFPU2-NEXT: stw 0, 4(1) |
| ; EFPU2-NEXT: stwu 1, -96(1) |
| ; EFPU2-NEXT: lwz 3, 0(3) |
| ; EFPU2-NEXT: stw 26, 72(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 27, 76(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 28, 80(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 29, 84(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: stw 30, 88(1) # 4-byte Folded Spill |
| ; EFPU2-NEXT: evstdd 26, 16(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: evstdd 27, 24(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: evstdd 28, 32(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: evstdd 29, 40(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: evstdd 30, 48(1) # 8-byte Folded Spill |
| ; EFPU2-NEXT: mr 30, 4 |
| ; EFPU2-NEXT: bl __extendsfdf2 |
| ; EFPU2-NEXT: mr 28, 3 |
| ; EFPU2-NEXT: lwz 3, 0(30) |
| ; EFPU2-NEXT: mr 29, 4 |
| ; EFPU2-NEXT: bl __extendsfdf2 |
| ; EFPU2-NEXT: mr 30, 4 |
| ; EFPU2-NEXT: mr 27, 3 |
| ; EFPU2-NEXT: bl foo |
| ; EFPU2-NEXT: mr 26, 3 |
| ; EFPU2-NEXT: mr 3, 28 |
| ; EFPU2-NEXT: mr 4, 29 |
| ; EFPU2-NEXT: bl foo |
| ; EFPU2-NEXT: mr 3, 26 |
| ; EFPU2-NEXT: bl __floatsidf |
| ; EFPU2-NEXT: mr 6, 4 |
| ; EFPU2-NEXT: mr 5, 3 |
| ; EFPU2-NEXT: mr 3, 27 |
| ; EFPU2-NEXT: mr 4, 30 |
| ; EFPU2-NEXT: bl __muldf3 |
| ; EFPU2-NEXT: bl __truncdfsf2 |
| ; EFPU2-NEXT: stw 3, 0(3) |
| ; EFPU2-NEXT: evldd 30, 48(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: evldd 29, 40(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: evldd 28, 32(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: evldd 27, 24(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: evldd 26, 16(1) # 8-byte Folded Reload |
| ; EFPU2-NEXT: lwz 30, 88(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 29, 84(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 28, 80(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 27, 76(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 26, 72(1) # 4-byte Folded Reload |
| ; EFPU2-NEXT: lwz 0, 100(1) |
| ; EFPU2-NEXT: addi 1, 1, 96 |
| ; EFPU2-NEXT: mtlr 0 |
| ; EFPU2-NEXT: blr |
| entry: |
| %0 = getelementptr %struct.a, %struct.a* %f, i32 0, i32 0 |
| %1 = load float, float* undef |
| %conv = fpext float %1 to double |
| %2 = load float, float* %0 |
| %g = fpext float %2 to double |
| %3 = call i32 @foo(double %g) |
| %h = call i32 @foo(double %conv) |
| %n = sitofp i32 %3 to double |
| %k = fmul double %g, %n |
| %l = fptrunc double %k to float |
| store float %l, float* undef |
| ret void |
| } |
| attributes #0 = { nounwind } |
| |
| ;--- hwdouble.ll |
| ; split into separate file because the efd* instructions are invalid on efpu2 |
| define i32 @test_dasmconst(double %x) #0 { |
| ; SPE-LABEL: test_dasmconst: |
| ; SPE: # %bb.0: # %entry |
| ; SPE-NEXT: stwu 1, -16(1) |
| ; SPE-NEXT: evmergelo 3, 3, 4 |
| ; SPE-NEXT: evstdd 3, 8(1) |
| ; SPE-NEXT: #APP |
| ; SPE-NEXT: efdctsi 3, 3 |
| ; SPE-NEXT: #NO_APP |
| ; SPE-NEXT: addi 1, 1, 16 |
| ; SPE-NEXT: blr |
| entry: |
| %x.addr = alloca double, align 8 |
| store double %x, double* %x.addr, align 8 |
| %0 = load double, double* %x.addr, align 8 |
| %1 = call i32 asm sideeffect "efdctsi $0, $1", "=d,d"(double %0) |
| ret i32 %1 |
| } |
| attributes #0 = { nounwind } |