[llvm] 29d2a9b - InstSimplify: Handle basic folds for frexp

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 17 14:34:46 PDT 2023


Author: Matt Arsenault
Date: 2023-07-17T17:28:01-04:00
New Revision: 29d2a9bf9dbf030b43bb46d5611a751c91defc02

URL: https://github.com/llvm/llvm-project/commit/29d2a9bf9dbf030b43bb46d5611a751c91defc02
DIFF: https://github.com/llvm/llvm-project/commit/29d2a9bf9dbf030b43bb46d5611a751c91defc02.diff

LOG: InstSimplify: Handle basic folds for frexp

Handle constant folding and idempotent folding. Not sure
this is an appropriate use of undef for the inf/nan case. The
C version says the second result is "unspecified". The AMDGPU
instruction returns 0.

Added: 
    

Modified: 
    llvm/lib/Analysis/ConstantFolding.cpp
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/frexp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index dfac88fa2d0efa..432be1e51de240 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1587,6 +1587,7 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
   case Intrinsic::powi:
   case Intrinsic::fma:
   case Intrinsic::fmuladd:
+  case Intrinsic::frexp:
   case Intrinsic::fptoui_sat:
   case Intrinsic::fptosi_sat:
   case Intrinsic::convert_from_fp16:
@@ -3294,6 +3295,69 @@ static Constant *ConstantFoldScalableVectorCall(
   return nullptr;
 }
 
+static std::pair<Constant *, Constant *>
+ConstantFoldScalarFrexpCall(Constant *Op, Type *IntTy) {
+  if (isa<PoisonValue>(Op))
+    return {Op, PoisonValue::get(IntTy)};
+
+  auto *ConstFP = dyn_cast<ConstantFP>(Op);
+  if (!ConstFP)
+    return {};
+
+  const APFloat &U = ConstFP->getValueAPF();
+  int FrexpExp;
+  APFloat FrexpMant = frexp(U, FrexpExp, APFloat::rmNearestTiesToEven);
+  Constant *Result0 = ConstantFP::get(ConstFP->getType(), FrexpMant);
+
+  // The exponent is an "unspecified value" for inf/nan. We use zero to avoid
+  // using undef.
+  Constant *Result1 = FrexpMant.isFinite() ? ConstantInt::get(IntTy, FrexpExp)
+                                           : ConstantInt::getNullValue(IntTy);
+  return {Result0, Result1};
+}
+
+/// Handle intrinsics that return tuples, which may be tuples of vectors.
+static Constant *
+ConstantFoldStructCall(StringRef Name, Intrinsic::ID IntrinsicID,
+                       StructType *StTy, ArrayRef<Constant *> Operands,
+                       const DataLayout &DL, const TargetLibraryInfo *TLI,
+                       const CallBase *Call) {
+
+  switch (IntrinsicID) {
+  case Intrinsic::frexp: {
+    Type *Ty0 = StTy->getContainedType(0);
+    Type *Ty1 = StTy->getContainedType(1)->getScalarType();
+
+    if (auto *FVTy0 = dyn_cast<FixedVectorType>(Ty0)) {
+      SmallVector<Constant *, 4> Results0(FVTy0->getNumElements());
+      SmallVector<Constant *, 4> Results1(FVTy0->getNumElements());
+
+      for (unsigned I = 0, E = FVTy0->getNumElements(); I != E; ++I) {
+        Constant *Lane = Operands[0]->getAggregateElement(I);
+        std::tie(Results0[I], Results1[I]) =
+            ConstantFoldScalarFrexpCall(Lane, Ty1);
+        if (!Results0[I])
+          return nullptr;
+      }
+
+      return ConstantStruct::get(StTy, ConstantVector::get(Results0),
+                                 ConstantVector::get(Results1));
+    }
+
+    auto [Result0, Result1] = ConstantFoldScalarFrexpCall(Operands[0], Ty1);
+    if (!Result0)
+      return nullptr;
+    return ConstantStruct::get(StTy, Result0, Result1);
+  }
+  default:
+    // TODO: Constant folding of vector intrinsics that fall through here does
+    // not work (e.g. overflow intrinsics)
+    return ConstantFoldScalarCall(Name, IntrinsicID, StTy, Operands, TLI, Call);
+  }
+
+  return nullptr;
+}
+
 } // end anonymous namespace
 
 Constant *llvm::ConstantFoldCall(const CallBase *Call, Function *F,
@@ -3305,7 +3369,8 @@ Constant *llvm::ConstantFoldCall(const CallBase *Call, Function *F,
     return nullptr;
 
   // If this is not an intrinsic and not recognized as a library call, bail out.
-  if (F->getIntrinsicID() == Intrinsic::not_intrinsic) {
+  Intrinsic::ID IID = F->getIntrinsicID();
+  if (IID == Intrinsic::not_intrinsic) {
     if (!TLI)
       return nullptr;
     LibFunc LibF;
@@ -3317,19 +3382,20 @@ Constant *llvm::ConstantFoldCall(const CallBase *Call, Function *F,
   Type *Ty = F->getReturnType();
   if (auto *FVTy = dyn_cast<FixedVectorType>(Ty))
     return ConstantFoldFixedVectorCall(
-        Name, F->getIntrinsicID(), FVTy, Operands,
-        F->getParent()->getDataLayout(), TLI, Call);
+        Name, IID, FVTy, Operands, F->getParent()->getDataLayout(), TLI, Call);
 
   if (auto *SVTy = dyn_cast<ScalableVectorType>(Ty))
     return ConstantFoldScalableVectorCall(
-        Name, F->getIntrinsicID(), SVTy, Operands,
-        F->getParent()->getDataLayout(), TLI, Call);
+        Name, IID, SVTy, Operands, F->getParent()->getDataLayout(), TLI, Call);
+
+  if (auto *StTy = dyn_cast<StructType>(Ty))
+    return ConstantFoldStructCall(Name, IID, StTy, Operands,
+                                  F->getParent()->getDataLayout(), TLI, Call);
 
   // TODO: If this is a library function, we already discovered that above,
   //       so we should pass the LibFunc, not the name (and it might be better
   //       still to separate intrinsic handling from libcalls).
-  return ConstantFoldScalarCall(Name, F->getIntrinsicID(), Ty, Operands, TLI,
-                                Call);
+  return ConstantFoldScalarCall(Name, IID, Ty, Operands, TLI, Call);
 }
 
 bool llvm::isMathLibCallNoop(const CallBase *Call,

diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 1c89de3b4cae55..4b4979374596ca 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -6159,6 +6159,15 @@ static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
     if (isSplatValue(Op0))
       return Op0;
     break;
+  case Intrinsic::frexp: {
+    // Frexp is idempotent with the added complication of the struct return.
+    if (match(Op0, m_ExtractValue<0>(m_Value(X)))) {
+      if (match(X, m_Intrinsic<Intrinsic::frexp>(m_Value())))
+        return X;
+    }
+
+    break;
+  }
   default:
     break;
   }

diff  --git a/llvm/test/Transforms/InstSimplify/frexp.ll b/llvm/test/Transforms/InstSimplify/frexp.ll
index ad15b50cff55d9..63fe1dec692933 100644
--- a/llvm/test/Transforms/InstSimplify/frexp.ll
+++ b/llvm/test/Transforms/InstSimplify/frexp.ll
@@ -12,9 +12,7 @@ define { float, i32 } @frexp_frexp(float %x) {
 ; CHECK-LABEL: define { float, i32 } @frexp_frexp
 ; CHECK-SAME: (float [[X:%.*]]) {
 ; CHECK-NEXT:    [[FREXP0:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[X]])
-; CHECK-NEXT:    [[FREXP0_0:%.*]] = extractvalue { float, i32 } [[FREXP0]], 0
-; CHECK-NEXT:    [[FREXP1:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[FREXP0_0]])
-; CHECK-NEXT:    ret { float, i32 } [[FREXP1]]
+; CHECK-NEXT:    ret { float, i32 } [[FREXP0]]
 ;
   %frexp0 = call { float, i32 } @llvm.frexp.f32.i32(float %x)
   %frexp0.0 = extractvalue { float, i32 } %frexp0, 0
@@ -26,9 +24,7 @@ define { <2 x float>, <2 x i32> } @frexp_frexp_vector(<2 x float> %x) {
 ; CHECK-LABEL: define { <2 x float>, <2 x i32> } @frexp_frexp_vector
 ; CHECK-SAME: (<2 x float> [[X:%.*]]) {
 ; CHECK-NEXT:    [[FREXP0:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> [[X]])
-; CHECK-NEXT:    [[FREXP0_0:%.*]] = extractvalue { <2 x float>, <2 x i32> } [[FREXP0]], 0
-; CHECK-NEXT:    [[FREXP1:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> [[FREXP0_0]])
-; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } [[FREXP1]]
+; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } [[FREXP0]]
 ;
   %frexp0 = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %x)
   %frexp0.0 = extractvalue { <2 x float>, <2 x i32> } %frexp0, 0
@@ -39,10 +35,7 @@ define { <2 x float>, <2 x i32> } @frexp_frexp_vector(<2 x float> %x) {
 define { float, i32 } @frexp_frexp_const(float %x) {
 ; CHECK-LABEL: define { float, i32 } @frexp_frexp_const
 ; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT:    [[FREXP0:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 4.200000e+01)
-; CHECK-NEXT:    [[FREXP0_0:%.*]] = extractvalue { float, i32 } [[FREXP0]], 0
-; CHECK-NEXT:    [[FREXP1:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float [[FREXP0_0]])
-; CHECK-NEXT:    ret { float, i32 } [[FREXP1]]
+; CHECK-NEXT:    ret { float, i32 } { float 6.562500e-01, i32 0 }
 ;
   %frexp0 = call { float, i32 } @llvm.frexp.f32.i32(float 42.0)
   %frexp0.0 = extractvalue { float, i32 } %frexp0, 0
@@ -54,9 +47,7 @@ define { <vscale x 2 x float>, <vscale x 2 x i32> } @frexp_frexp_scalable_vector
 ; CHECK-LABEL: define { <vscale x 2 x float>, <vscale x 2 x i32> } @frexp_frexp_scalable_vector
 ; CHECK-SAME: (<vscale x 2 x float> [[X:%.*]]) {
 ; CHECK-NEXT:    [[FREXP0:%.*]] = call { <vscale x 2 x float>, <vscale x 2 x i32> } @llvm.frexp.nxv2f32.nxv2i32(<vscale x 2 x float> [[X]])
-; CHECK-NEXT:    [[FREXP0_0:%.*]] = extractvalue { <vscale x 2 x float>, <vscale x 2 x i32> } [[FREXP0]], 0
-; CHECK-NEXT:    [[FREXP1:%.*]] = call { <vscale x 2 x float>, <vscale x 2 x i32> } @llvm.frexp.nxv2f32.nxv2i32(<vscale x 2 x float> [[FREXP0_0]])
-; CHECK-NEXT:    ret { <vscale x 2 x float>, <vscale x 2 x i32> } [[FREXP1]]
+; CHECK-NEXT:    ret { <vscale x 2 x float>, <vscale x 2 x i32> } [[FREXP0]]
 ;
   %frexp0 = call { <vscale x 2 x float>, <vscale x 2 x i32> } @llvm.frexp.nxv2f32.nxv2i32(<vscale x 2 x float> %x)
   %frexp0.0 = extractvalue { <vscale x 2 x float>, <vscale x 2 x i32> } %frexp0, 0
@@ -66,8 +57,7 @@ define { <vscale x 2 x float>, <vscale x 2 x i32> } @frexp_frexp_scalable_vector
 
 define { float, i32 } @frexp_poison() {
 ; CHECK-LABEL: define { float, i32 } @frexp_poison() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float poison)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } poison
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float poison)
   ret { float, i32 } %ret
@@ -75,8 +65,7 @@ define { float, i32 } @frexp_poison() {
 
 define { <2 x float>, <2 x i32> } @frexp_poison_vector() {
 ; CHECK-LABEL: define { <2 x float>, <2 x i32> } @frexp_poison_vector() {
-; CHECK-NEXT:    [[RET:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> poison)
-; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } [[RET]]
+; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } poison
 ;
   %ret = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> poison)
   ret { <2 x float>, <2 x i32> } %ret
@@ -84,8 +73,7 @@ define { <2 x float>, <2 x i32> } @frexp_poison_vector() {
 
 define { <vscale x 2 x float>, <vscale x 2 x i32> } @frexp_poison_scaleable_vector() {
 ; CHECK-LABEL: define { <vscale x 2 x float>, <vscale x 2 x i32> } @frexp_poison_scaleable_vector() {
-; CHECK-NEXT:    [[RET:%.*]] = call { <vscale x 2 x float>, <vscale x 2 x i32> } @llvm.frexp.nxv2f32.nxv2i32(<vscale x 2 x float> poison)
-; CHECK-NEXT:    ret { <vscale x 2 x float>, <vscale x 2 x i32> } [[RET]]
+; CHECK-NEXT:    ret { <vscale x 2 x float>, <vscale x 2 x i32> } poison
 ;
   %ret = call { <vscale x 2 x float>, <vscale x 2 x i32> } @llvm.frexp.nxv2f32.nxv2i32(<vscale x 2 x float> poison)
   ret { <vscale x 2 x float>, <vscale x 2 x i32> } %ret
@@ -110,8 +98,7 @@ define { <2 x float>, <2 x i32> } @frexp_undef_vector() {
 
 define { <2 x float>, <2 x i32> } @frexp_zero_vector() {
 ; CHECK-LABEL: define { <2 x float>, <2 x i32> } @frexp_zero_vector() {
-; CHECK-NEXT:    [[RET:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> zeroinitializer)
-; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } [[RET]]
+; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } zeroinitializer
 ;
   %ret = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> zeroinitializer)
   ret { <2 x float>, <2 x i32> } %ret
@@ -128,8 +115,7 @@ define { <vscale x 2 x float>, <vscale x 2 x i32> } @frexp_zero_scalable_vector(
 
 define { <2 x float>, <2 x i32> } @frexp_zero_negzero_vector() {
 ; CHECK-LABEL: define { <2 x float>, <2 x i32> } @frexp_zero_negzero_vector() {
-; CHECK-NEXT:    [[RET:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> <float 0.000000e+00, float -0.000000e+00>)
-; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } [[RET]]
+; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } { <2 x float> <float 0.000000e+00, float -0.000000e+00>, <2 x i32> zeroinitializer }
 ;
   %ret = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> <float 0.0, float -0.0>)
   ret { <2 x float>, <2 x i32> } %ret
@@ -146,8 +132,7 @@ define { <4 x float>, <4 x i32> } @frexp_nonsplat_vector() {
 
 define { float, i32 } @frexp_zero() {
 ; CHECK-LABEL: define { float, i32 } @frexp_zero() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 0.000000e+00)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } zeroinitializer
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float 0.0)
   ret { float, i32 } %ret
@@ -155,8 +140,7 @@ define { float, i32 } @frexp_zero() {
 
 define { float, i32 } @frexp_negzero() {
 ; CHECK-LABEL: define { float, i32 } @frexp_negzero() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float -0.000000e+00)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } { float -0.000000e+00, i32 0 }
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float -0.0)
   ret { float, i32 } %ret
@@ -164,8 +148,7 @@ define { float, i32 } @frexp_negzero() {
 
 define { float, i32 } @frexp_one() {
 ; CHECK-LABEL: define { float, i32 } @frexp_one() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 1.000000e+00)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } { float 5.000000e-01, i32 1 }
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float 1.0)
   ret { float, i32 } %ret
@@ -173,8 +156,7 @@ define { float, i32 } @frexp_one() {
 
 define { float, i32 } @frexp_negone() {
 ; CHECK-LABEL: define { float, i32 } @frexp_negone() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float -1.000000e+00)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } { float -5.000000e-01, i32 1 }
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float -1.0)
   ret { float, i32 } %ret
@@ -182,8 +164,7 @@ define { float, i32 } @frexp_negone() {
 
 define { float, i32 } @frexp_two() {
 ; CHECK-LABEL: define { float, i32 } @frexp_two() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 2.000000e+00)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } { float 5.000000e-01, i32 2 }
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float 2.0)
   ret { float, i32 } %ret
@@ -191,8 +172,7 @@ define { float, i32 } @frexp_two() {
 
 define { float, i32 } @frexp_negtwo() {
 ; CHECK-LABEL: define { float, i32 } @frexp_negtwo() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float -2.000000e+00)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } { float -5.000000e-01, i32 2 }
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float -2.0)
   ret { float, i32 } %ret
@@ -200,8 +180,7 @@ define { float, i32 } @frexp_negtwo() {
 
 define { float, i32 } @frexp_inf() {
 ; CHECK-LABEL: define { float, i32 } @frexp_inf() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 0x7FF0000000000000)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } { float 0x7FF0000000000000, i32 0 }
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float 0x7FF0000000000000)
   ret { float, i32 } %ret
@@ -209,8 +188,7 @@ define { float, i32 } @frexp_inf() {
 
 define { float, i32 } @frexp_neginf() {
 ; CHECK-LABEL: define { float, i32 } @frexp_neginf() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 0xFFF0000000000000)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } { float 0xFFF0000000000000, i32 0 }
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float 0xFFF0000000000000)
   ret { float, i32 } %ret
@@ -218,8 +196,7 @@ define { float, i32 } @frexp_neginf() {
 
 define { float, i32 } @frexp_qnan() {
 ; CHECK-LABEL: define { float, i32 } @frexp_qnan() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 0x7FF8000000000000)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } { float 0x7FF8000000000000, i32 0 }
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float 0x7FF8000000000000)
   ret { float, i32 } %ret
@@ -227,8 +204,7 @@ define { float, i32 } @frexp_qnan() {
 
 define { float, i32 } @frexp_snan() {
 ; CHECK-LABEL: define { float, i32 } @frexp_snan() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 0x7FF0000020000000)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } { float 0x7FF8000020000000, i32 0 }
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float bitcast (i32 2139095041 to float))
   ret { float, i32 } %ret
@@ -236,8 +212,7 @@ define { float, i32 } @frexp_snan() {
 
 define { float, i32 } @frexp_pos_denorm() {
 ; CHECK-LABEL: define { float, i32 } @frexp_pos_denorm() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 0x380FFFFFC0000000)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } { float 0x3FEFFFFFC0000000, i32 -126 }
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float bitcast (i32 8388607 to float))
   ret { float, i32 } %ret
@@ -245,8 +220,7 @@ define { float, i32 } @frexp_pos_denorm() {
 
 define { float, i32 } @frexp_neg_denorm() {
 ; CHECK-LABEL: define { float, i32 } @frexp_neg_denorm() {
-; CHECK-NEXT:    [[RET:%.*]] = call { float, i32 } @llvm.frexp.f32.i32(float 0xB80FFFFFC0000000)
-; CHECK-NEXT:    ret { float, i32 } [[RET]]
+; CHECK-NEXT:    ret { float, i32 } { float 0xBFEFFFFFC0000000, i32 -126 }
 ;
   %ret = call { float, i32 } @llvm.frexp.f32.i32(float bitcast (i32 -2139095041 to float))
   ret { float, i32 } %ret
@@ -254,8 +228,7 @@ define { float, i32 } @frexp_neg_denorm() {
 
 define { ppc_fp128, i32 } @frexp_one_ppcf128() {
 ; CHECK-LABEL: define { ppc_fp128, i32 } @frexp_one_ppcf128() {
-; CHECK-NEXT:    [[RET:%.*]] = call { ppc_fp128, i32 } @llvm.frexp.ppcf128.i32(ppc_fp128 0xM3FF00000000000000000000000000000)
-; CHECK-NEXT:    ret { ppc_fp128, i32 } [[RET]]
+; CHECK-NEXT:    ret { ppc_fp128, i32 } { ppc_fp128 0xM3FE00000000000000000000000000000, i32 1 }
 ;
   %ret = call { ppc_fp128, i32 } @llvm.frexp.ppcf128.i32(ppc_fp128 0xM3FF00000000000000000000000000000)
   ret { ppc_fp128, i32 } %ret
@@ -263,8 +236,7 @@ define { ppc_fp128, i32 } @frexp_one_ppcf128() {
 
 define { ppc_fp128, i32 } @frexp_negone_ppcf128() {
 ; CHECK-LABEL: define { ppc_fp128, i32 } @frexp_negone_ppcf128() {
-; CHECK-NEXT:    [[RET:%.*]] = call { ppc_fp128, i32 } @llvm.frexp.ppcf128.i32(ppc_fp128 0xMBFF00000000000000000000000000000)
-; CHECK-NEXT:    ret { ppc_fp128, i32 } [[RET]]
+; CHECK-NEXT:    ret { ppc_fp128, i32 } { ppc_fp128 0xMBFE00000000000000000000000000000, i32 1 }
 ;
   %ret = call { ppc_fp128, i32 } @llvm.frexp.ppcf128.i32(ppc_fp128 0xMBFF00000000000000000000000000000)
   ret { ppc_fp128, i32 } %ret
@@ -272,8 +244,7 @@ define { ppc_fp128, i32 } @frexp_negone_ppcf128() {
 
 define { ppc_fp128, i32} @canonicalize_noncanonical_zero_1_ppcf128() {
 ; CHECK-LABEL: define { ppc_fp128, i32 } @canonicalize_noncanonical_zero_1_ppcf128() {
-; CHECK-NEXT:    [[RET:%.*]] = call { ppc_fp128, i32 } @llvm.frexp.ppcf128.i32(ppc_fp128 0xM00000000000000000000000000000001)
-; CHECK-NEXT:    ret { ppc_fp128, i32 } [[RET]]
+; CHECK-NEXT:    ret { ppc_fp128, i32 } { ppc_fp128 0xM00000000000000000000000000000001, i32 0 }
 ;
   %ret = call { ppc_fp128, i32 } @llvm.frexp.ppcf128.i32(ppc_fp128 0xM00000000000000000000000000000001)
   ret { ppc_fp128, i32 } %ret
@@ -281,8 +252,7 @@ define { ppc_fp128, i32} @canonicalize_noncanonical_zero_1_ppcf128() {
 
 define { <2 x float>, <2 x i32> } @frexp_splat_4() {
 ; CHECK-LABEL: define { <2 x float>, <2 x i32> } @frexp_splat_4() {
-; CHECK-NEXT:    [[RET:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> <float 4.000000e+00, float 4.000000e+00>)
-; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } [[RET]]
+; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } { <2 x float> <float 5.000000e-01, float 5.000000e-01>, <2 x i32> <i32 3, i32 3> }
 ;
   %ret = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> <float 4.0, float 4.0>)
   ret { <2 x float>, <2 x i32> } %ret
@@ -290,8 +260,7 @@ define { <2 x float>, <2 x i32> } @frexp_splat_4() {
 
 define { <2 x float>, <2 x i32> } @frexp_splat_qnan() {
 ; CHECK-LABEL: define { <2 x float>, <2 x i32> } @frexp_splat_qnan() {
-; CHECK-NEXT:    [[RET:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>)
-; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } [[RET]]
+; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } { <2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>, <2 x i32> zeroinitializer }
 ;
   %ret = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000>)
   ret { <2 x float>, <2 x i32> } %ret
@@ -299,8 +268,7 @@ define { <2 x float>, <2 x i32> } @frexp_splat_qnan() {
 
 define { <2 x float>, <2 x i32> } @frexp_splat_inf() {
 ; CHECK-LABEL: define { <2 x float>, <2 x i32> } @frexp_splat_inf() {
-; CHECK-NEXT:    [[RET:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>)
-; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } [[RET]]
+; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } { <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, <2 x i32> zeroinitializer }
 ;
   %ret = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>)
   ret { <2 x float>, <2 x i32> } %ret
@@ -308,8 +276,7 @@ define { <2 x float>, <2 x i32> } @frexp_splat_inf() {
 
 define { <2 x float>, <2 x i32> } @frexp_splat_neginf() {
 ; CHECK-LABEL: define { <2 x float>, <2 x i32> } @frexp_splat_neginf() {
-; CHECK-NEXT:    [[RET:%.*]] = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> <float 0xFFF0000000000000, float 0xFFF0000000000000>)
-; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } [[RET]]
+; CHECK-NEXT:    ret { <2 x float>, <2 x i32> } { <2 x float> <float 0xFFF0000000000000, float 0xFFF0000000000000>, <2 x i32> zeroinitializer }
 ;
   %ret = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> <float 0xFFF0000000000000, float 0xFFF0000000000000>)
   ret { <2 x float>, <2 x i32> } %ret


        


More information about the llvm-commits mailing list