[flang-commits] [clang-tools-extra] [libclc] [lld] [flang] [libcxx] [libunwind] [clang] [libcxxabi] [lldb] [libc] [llvm] [compiler-rt] [Legalizer] Soften EXTRACT_ELEMENT on ppcf128 (PR #77412)

Qiu Chaofan via flang-commits flang-commits at lists.llvm.org
Tue Jan 9 23:05:43 PST 2024


https://github.com/ecnelises updated https://github.com/llvm/llvm-project/pull/77412

>From 87e1d4acdd87d45f265e590ad135e21f352dc5ad Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Tue, 9 Jan 2024 13:33:56 +0800
Subject: [PATCH 1/3] [Legalizer] Soften EXTRACT_ELEMENT on ppcf128

ppc_fp128 values are always split into two f64. Implement soften
operation in soft-float mode to handle output f64 correctly.
---
 .../CodeGen/SelectionDAG/LegalizeFloatTypes.cpp    | 14 +++++++++++++-
 llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h      |  1 +
 llvm/test/CodeGen/PowerPC/ppcsoftops.ll            | 10 ++++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 6e0e1e23419bec..69759a7d6471f6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -60,7 +60,9 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
 #endif
     report_fatal_error("Do not know how to soften the result of this "
                        "operator!");
-
+    case ISD::EXTRACT_ELEMENT:
+      R = SoftenFloatRes_EXTRACT_ELEMENT(N);
+      break;
     case ISD::ARITH_FENCE: R = SoftenFloatRes_ARITH_FENCE(N); break;
     case ISD::MERGE_VALUES:R = SoftenFloatRes_MERGE_VALUES(N, ResNo); break;
     case ISD::BITCAST:     R = SoftenFloatRes_BITCAST(N); break;
@@ -262,6 +264,16 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(SDNode *N) {
   }
 }
 
+SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(SDNode *N) {
+  SDValue Src = N->getOperand(0);
+  assert(Src.getValueType() == MVT::ppcf128 &&
+         Src.getOperand(0)->getOpcode() == ISD::BUILD_PAIR &&
+         "In floats only ppcf128 can be extracted by element!");
+  EVT DestVT = EVT::getIntegerVT(*DAG.getContext(), N->getValueSizeInBits(0));
+  return DAG.getNode(ISD::EXTRACT_ELEMENT, SDLoc(N), DestVT,
+                     Src.getOperand(0), N->getOperand(1));
+}
+
 SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo) {
   SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0));
   return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N),
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 09f0bca8b8611e..efe8ac536b63bd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -541,6 +541,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue SoftenFloatRes_BITCAST(SDNode *N);
   SDValue SoftenFloatRes_BUILD_PAIR(SDNode *N);
   SDValue SoftenFloatRes_ConstantFP(SDNode *N);
+  SDValue SoftenFloatRes_EXTRACT_ELEMENT(SDNode *N);
   SDValue SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo);
   SDValue SoftenFloatRes_FABS(SDNode *N);
   SDValue SoftenFloatRes_FMINNUM(SDNode *N);
diff --git a/llvm/test/CodeGen/PowerPC/ppcsoftops.ll b/llvm/test/CodeGen/PowerPC/ppcsoftops.ll
index 0ee30f67c30f24..4c74798cf0ea5b 100644
--- a/llvm/test/CodeGen/PowerPC/ppcsoftops.ll
+++ b/llvm/test/CodeGen/PowerPC/ppcsoftops.ll
@@ -68,8 +68,18 @@ define dso_local zeroext i32 @func(double noundef %0, double noundef %1) #0 {
   ; CHECK-LABEL:      __adddf3
 }
 
+; To check ppc_fp128 soften without crash
+define zeroext i1 @ppcf128_soften(ppc_fp128 %a) #0 {
+entry:
+  %0 = tail call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %a, i32 100)
+  ret i1 %0
+
+  ; CHECK-LABEL: ppcf128_soften
+}
+
 ; 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" }
 attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

>From 2a222d9adcd086b9b25724ed31ae1478100e334a Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Wed, 10 Jan 2024 10:46:32 +0800
Subject: [PATCH 2/3] Use changeTypeToInteger

---
 llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 5 ++---
 llvm/test/CodeGen/PowerPC/ppcsoftops.ll              | 4 ++--
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index ecbf3ce94a3807..fac2a85e77b7b9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -267,10 +267,9 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(SDNode *N) {
 SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(SDNode *N) {
   SDValue Src = N->getOperand(0);
   assert(Src.getValueType() == MVT::ppcf128 &&
-         Src.getOperand(0)->getOpcode() == ISD::BUILD_PAIR &&
          "In floats only ppcf128 can be extracted by element!");
-  EVT DestVT = EVT::getIntegerVT(*DAG.getContext(), N->getValueSizeInBits(0));
-  return DAG.getNode(ISD::EXTRACT_ELEMENT, SDLoc(N), DestVT,
+  return DAG.getNode(ISD::EXTRACT_ELEMENT, SDLoc(N),
+                     N->getValueType(0).changeTypeToInteger(),
                      Src.getOperand(0), N->getOperand(1));
 }
 
diff --git a/llvm/test/CodeGen/PowerPC/ppcsoftops.ll b/llvm/test/CodeGen/PowerPC/ppcsoftops.ll
index 4c74798cf0ea5b..5a72ae4799ca7a 100644
--- a/llvm/test/CodeGen/PowerPC/ppcsoftops.ll
+++ b/llvm/test/CodeGen/PowerPC/ppcsoftops.ll
@@ -71,8 +71,8 @@ define dso_local zeroext i32 @func(double noundef %0, double noundef %1) #0 {
 ; To check ppc_fp128 soften without crash
 define zeroext i1 @ppcf128_soften(ppc_fp128 %a) #0 {
 entry:
-  %0 = tail call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %a, i32 100)
-  ret i1 %0
+  %fpclass = tail call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %a, i32 100)
+  ret i1 %fpclass
 
   ; CHECK-LABEL: ppcf128_soften
 }

>From 665cef1fc5417c2d87ce766c7f2b50815d1dc2c1 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Wed, 10 Jan 2024 15:05:20 +0800
Subject: [PATCH 3/3] Regenerate the case

---
 llvm/test/CodeGen/PowerPC/ppcsoftops.ll | 328 ++++++++++++++++++++++--
 1 file changed, 311 insertions(+), 17 deletions(-)

diff --git a/llvm/test/CodeGen/PowerPC/ppcsoftops.ll b/llvm/test/CodeGen/PowerPC/ppcsoftops.ll
index 5a72ae4799ca7a..f1a6aebbbe8b1d 100644
--- a/llvm/test/CodeGen/PowerPC/ppcsoftops.ll
+++ b/llvm/test/CodeGen/PowerPC/ppcsoftops.ll
@@ -1,9 +1,52 @@
-; RUN: llc -verify-machineinstrs  -mtriple=powerpc-unknown-linux-gnu -O0 < %s | FileCheck %s
-; RUN: llc -verify-machineinstrs  -mtriple=powerpc64-unknown-linux-gnu -O0 < %s | FileCheck %s
-; RUN: llc -verify-machineinstrs  -mtriple=powerpc64le-unknown-linux-gnu -O0 < %s | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -verify-machineinstrs  -mtriple=powerpc-unknown-linux-gnu -O0 < %s | FileCheck %s --check-prefix=PPC
+; RUN: llc -verify-machineinstrs  -mtriple=powerpc64-unknown-linux-gnu -O0 < %s | FileCheck %s --check-prefix=PPC64
+; RUN: llc -verify-machineinstrs  -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
@@ -11,11 +54,51 @@ entry:
   %1 = load double, ptr %b, align 8
   %add = fadd double %0, %1
   ret double %add
-
-  ; CHECK-LABEL:      __adddf3
 }
 
 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
@@ -23,11 +106,51 @@ entry:
   %1 = load double, ptr %b, align 8
   %mul = fmul double %0, %1
   ret double %mul
-
-  ; CHECK-LABEL:      __muldf3
 }
 
 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
@@ -35,11 +158,51 @@ entry:
   %1 = load double, ptr %b, align 8
   %sub = fsub double %0, %1
   ret double %sub
-
-  ; CHECK-LABEL:      __subdf3
 }
 
 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
@@ -47,12 +210,96 @@ entry:
   %1 = load double, ptr %b, align 8
   %div = fdiv double %0, %1
   ret double %div
-
-  ; CHECK-LABEL:      __divdf3
 }
 
 ; 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
@@ -63,23 +310,70 @@ define dso_local zeroext i32 @func(double noundef %0, double noundef %1) #0 {
   %8 = call double @llvm.fmuladd.f64(double %7, double 0x41F0000000000000, double %5)
   %9 = fptoui double %8 to i32
   ret i32 %9
-
-  ; CHECK-LABEL:      __muldf3
-  ; CHECK-LABEL:      __adddf3
 }
 
 ; 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
-
-  ; CHECK-LABEL: ppcf128_soften
 }
 
 ; 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" }
+attributes #0 = {"use-soft-float"="true" nounwind }
 attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }



More information about the flang-commits mailing list