[llvm] 9c54ee4 - [SimplifyLibCalls] Take size of int into consideration when emitting ldexp/ldexpf

Bjorn Pettersson via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 2 02:41:50 PDT 2021


Author: Bjorn Pettersson
Date: 2021-06-02T11:40:34+02:00
New Revision: 9c54ee437898314f956cfc048d9038ca775ea692

URL: https://github.com/llvm/llvm-project/commit/9c54ee437898314f956cfc048d9038ca775ea692
DIFF: https://github.com/llvm/llvm-project/commit/9c54ee437898314f956cfc048d9038ca775ea692.diff

LOG: [SimplifyLibCalls] Take size of int into consideration when emitting ldexp/ldexpf

When rewriting
  powf(2.0, itofp(x)) -> ldexpf(1.0, x)
  exp2(sitofp(x)) -> ldexp(1.0, sext(x))
  exp2(uitofp(x)) -> ldexp(1.0, zext(x))

the wrong type was used for the second argument in the ldexp/ldexpf
libc call, for target architectures with 16 bit "int" type.
The transform incorrectly used a bitcasted function pointer with
a 32-bit argument when emitting the ldexp/ldexpf call for such
targets.

The fault is solved by using the correct function prototype
in the call, by asking TargetLibraryInfo about the size of "int".
TargetLibraryInfo by default derives the size of the int type by
assuming that it is 16 bits for 16-bit architectures, and
32 bits otherwise. If this isn't true for a target it should be
possible to override that default in the TargetLibraryInfo
initializer.

Differential Revision: https://reviews.llvm.org/D99438

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/TargetLibraryInfo.h
    llvm/lib/Analysis/TargetLibraryInfo.cpp
    llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
    llvm/test/Transforms/InstCombine/exp2-1.ll
    llvm/test/Transforms/InstCombine/pow_fp_int.ll
    llvm/test/Transforms/InstCombine/simplify-libcalls.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index a7ad218356afb..22bfeda0efd0d 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -52,6 +52,7 @@ class TargetLibraryInfoImpl {
   llvm::DenseMap<unsigned, std::string> CustomNames;
   static StringLiteral const StandardNames[NumLibFuncs];
   bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param;
+  unsigned SizeOfInt;
 
   enum AvailabilityState {
     StandardName = 3, // (memset to all ones)
@@ -189,6 +190,16 @@ class TargetLibraryInfoImpl {
   /// This queries the 'wchar_size' metadata.
   unsigned getWCharSize(const Module &M) const;
 
+  /// Get size of a C-level int or unsigned int, in bits.
+  unsigned getIntSize() const {
+    return SizeOfInt;
+  }
+
+  /// Initialize the C-level size of an integer.
+  void setIntSize(unsigned Bits) {
+    SizeOfInt = Bits;
+  }
+
   /// Returns the largest vectorization factor used in the list of
   /// vector functions.
   void getWidestVF(StringRef ScalarF, ElementCount &FixedVF,
@@ -390,6 +401,11 @@ class TargetLibraryInfo {
     return Impl->getWCharSize(M);
   }
 
+  /// \copydoc TargetLibraryInfoImpl::getIntSize()
+  unsigned getIntSize() const {
+    return Impl->getIntSize();
+  }
+
   /// Handle invalidation from the pass manager.
   ///
   /// If we try to invalidate this info, just return false. It cannot become

diff  --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 05088c189ca22..d078cce5e8ee7 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -151,6 +151,11 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
   TLI.setShouldExtI32Return(ShouldExtI32Return);
   TLI.setShouldSignExtI32Param(ShouldSignExtI32Param);
 
+  // Let's assume by default that the size of int is 32 bits, unless the target
+  // is a 16-bit architecture because then it most likely is 16 bits. If that
+  // isn't true for a target those defaults should be overridden below.
+  TLI.setIntSize(T.isArch16Bit() ? 16 : 32);
+
   if (T.isAMDGPU())
     TLI.disableAllFunctions();
 
@@ -639,7 +644,8 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) {
 TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI)
     : CustomNames(TLI.CustomNames), ShouldExtI32Param(TLI.ShouldExtI32Param),
       ShouldExtI32Return(TLI.ShouldExtI32Return),
-      ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) {
+      ShouldSignExtI32Param(TLI.ShouldSignExtI32Param),
+      SizeOfInt(TLI.SizeOfInt) {
   memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
   VectorDescs = TLI.VectorDescs;
   ScalarDescs = TLI.ScalarDescs;
@@ -649,7 +655,8 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)
     : CustomNames(std::move(TLI.CustomNames)),
       ShouldExtI32Param(TLI.ShouldExtI32Param),
       ShouldExtI32Return(TLI.ShouldExtI32Return),
-      ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) {
+      ShouldSignExtI32Param(TLI.ShouldSignExtI32Param),
+      SizeOfInt(TLI.SizeOfInt) {
   std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
             AvailableArray);
   VectorDescs = TLI.VectorDescs;
@@ -661,6 +668,7 @@ TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoI
   ShouldExtI32Param = TLI.ShouldExtI32Param;
   ShouldExtI32Return = TLI.ShouldExtI32Return;
   ShouldSignExtI32Param = TLI.ShouldSignExtI32Param;
+  SizeOfInt = TLI.SizeOfInt;
   memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
   return *this;
 }
@@ -670,6 +678,7 @@ TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&
   ShouldExtI32Param = TLI.ShouldExtI32Param;
   ShouldExtI32Return = TLI.ShouldExtI32Return;
   ShouldSignExtI32Param = TLI.ShouldSignExtI32Param;
+  SizeOfInt = TLI.SizeOfInt;
   std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
             AvailableArray);
   return *this;
@@ -1498,7 +1507,7 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
   case LibFunc_ldexpl:
     return (NumParams == 2 && FTy.getReturnType()->isFloatingPointTy() &&
             FTy.getReturnType() == FTy.getParamType(0) &&
-            FTy.getParamType(1)->isIntegerTy(32));
+            FTy.getParamType(1)->isIntegerTy(getIntSize()));
 
   case LibFunc_ffs:
   case LibFunc_ffsl:

diff  --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index e9f777faf9c6b..5b650f8c5dd7c 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -1424,17 +1424,18 @@ static Value *getPow(Value *InnerChain[33], unsigned Exp, IRBuilderBase &B) {
   return InnerChain[Exp];
 }
 
-// Return a properly extended 32-bit integer if the operation is an itofp.
-static Value *getIntToFPVal(Value *I2F, IRBuilderBase &B) {
+// Return a properly extended integer (DstWidth bits wide) if the operation is
+// an itofp.
+static Value *getIntToFPVal(Value *I2F, IRBuilderBase &B, unsigned DstWidth) {
   if (isa<SIToFPInst>(I2F) || isa<UIToFPInst>(I2F)) {
     Value *Op = cast<Instruction>(I2F)->getOperand(0);
-    // Make sure that the exponent fits inside an int32_t,
+    // Make sure that the exponent fits inside an "int" of size DstWidth,
     // thus avoiding any range issues that FP has not.
     unsigned BitWidth = Op->getType()->getPrimitiveSizeInBits();
-    if (BitWidth < 32 ||
-        (BitWidth == 32 && isa<SIToFPInst>(I2F)))
-      return isa<SIToFPInst>(I2F) ? B.CreateSExt(Op, B.getInt32Ty())
-                                  : B.CreateZExt(Op, B.getInt32Ty());
+    if (BitWidth < DstWidth ||
+        (BitWidth == DstWidth && isa<SIToFPInst>(I2F)))
+      return isa<SIToFPInst>(I2F) ? B.CreateSExt(Op, B.getIntNTy(DstWidth))
+                                  : B.CreateZExt(Op, B.getIntNTy(DstWidth));
   }
 
   return nullptr;
@@ -1524,7 +1525,7 @@ Value *LibCallSimplifier::replacePowWithExp(CallInst *Pow, IRBuilderBase &B) {
   if (match(Base, m_SpecificFP(2.0)) &&
       (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
       hasFloatFn(TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
-    if (Value *ExpoI = getIntToFPVal(Expo, B))
+    if (Value *ExpoI = getIntToFPVal(Expo, B, TLI->getIntSize()))
       return emitBinaryFloatFnCall(ConstantFP::get(Ty, 1.0), ExpoI, TLI,
                                    LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl,
                                    B, Attrs);
@@ -1776,7 +1777,12 @@ Value *LibCallSimplifier::optimizePow(CallInst *Pow, IRBuilderBase &B) {
 
   // powf(x, itofp(y)) -> powi(x, y)
   if (AllowApprox && (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo))) {
-    if (Value *ExpoI = getIntToFPVal(Expo, B))
+    // FIXME: Currently we always use 32 bits for the exponent in llvm.powi. In
+    // the future we want to use the target dependent "size of int", or
+    // otherwise we could end up using the wrong type for the exponent when
+    // mapping llvm.powi back to an rtlib call. See
+    // https://reviews.llvm.org/D99439 for such a fix.
+    if (Value *ExpoI = getIntToFPVal(Expo, B, 32))
       return createPowWithIntegerExponent(Base, ExpoI, M, B);
   }
 
@@ -1803,11 +1809,11 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) {
   Type *Ty = CI->getType();
   Value *Op = CI->getArgOperand(0);
 
-  // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x))  if sizeof(x) <= 32
-  // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x))  if sizeof(x) < 32
+  // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x))  if sizeof(x) <= IntSize
+  // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x))  if sizeof(x) < IntSize
   if ((isa<SIToFPInst>(Op) || isa<UIToFPInst>(Op)) &&
       hasFloatFn(TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
-    if (Value *Exp = getIntToFPVal(Op, B))
+    if (Value *Exp = getIntToFPVal(Op, B, TLI->getIntSize()))
       return emitBinaryFloatFnCall(ConstantFP::get(Ty, 1.0), Exp, TLI,
                                    LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl,
                                    B, Attrs);

diff  --git a/llvm/test/Transforms/InstCombine/exp2-1.ll b/llvm/test/Transforms/InstCombine/exp2-1.ll
index b6a56b9a9a7e5..afb104ffe819d 100644
--- a/llvm/test/Transforms/InstCombine/exp2-1.ll
+++ b/llvm/test/Transforms/InstCombine/exp2-1.ll
@@ -1,8 +1,10 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; Test that the exp2 library call simplifier works correctly.
 ;
-; RUN: opt < %s -instcombine -S | FileCheck %s -check-prefix=CHECK -check-prefix=INTRINSIC -check-prefix=LDEXP -check-prefix=LDEXPF
-; RUN: opt < %s -instcombine -S -mtriple=i386-pc-win32 | FileCheck %s -check-prefix=INTRINSIC -check-prefix=LDEXP -check-prefix=NOLDEXPF
-; RUN: opt < %s -instcombine -S -mtriple=amdgcn-unknown-unknown | FileCheck %s -check-prefix=INTRINSIC -check-prefix=NOLDEXP -check-prefix=NOLDEXPF
+; RUN: opt < %s -instcombine -S -mtriple=unknown | FileCheck %s -check-prefixes=LDEXP32
+; RUN: opt < %s -instcombine -S -mtriple=msp430 | FileCheck %s -check-prefixes=LDEXP16
+; RUN: opt < %s -instcombine -S -mtriple=i386-pc-win32 | FileCheck %s -check-prefixes=NOLDEXPF
+; RUN: opt < %s -instcombine -S -mtriple=amdgcn-unknown-unknown | FileCheck %s -check-prefixes=NOLDEXP
 
 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
 
@@ -12,68 +14,208 @@ declare float @exp2f(float)
 ; Check exp2(sitofp(x)) -> ldexp(1.0, sext(x)).
 
 define double @test_simplify1(i32 %x) {
-; CHECK-LABEL: @test_simplify1(
+; LDEXP32-LABEL: @test_simplify1(
+; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[X:%.*]])
+; LDEXP32-NEXT:    ret double [[LDEXP]]
+;
+; LDEXP16-LABEL: @test_simplify1(
+; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to double
+; LDEXP16-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
+; LDEXP16-NEXT:    ret double [[RET]]
+;
+; NOLDEXPF-LABEL: @test_simplify1(
+; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[X:%.*]])
+; NOLDEXPF-NEXT:    ret double [[LDEXP]]
+;
+; NOLDEXP-LABEL: @test_simplify1(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to double
+; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
+; NOLDEXP-NEXT:    ret double [[RET]]
+;
   %conv = sitofp i32 %x to double
   %ret = call double @exp2(double %conv)
-; CHECK: call double @ldexp
   ret double %ret
 }
 
 define double @test_simplify2(i16 signext %x) {
-; CHECK-LABEL: @test_simplify2(
+; LDEXP32-LABEL: @test_simplify2(
+; LDEXP32-NEXT:    [[TMP1:%.*]] = sext i16 [[X:%.*]] to i32
+; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret double [[LDEXP]]
+;
+; LDEXP16-LABEL: @test_simplify2(
+; LDEXP16-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i16 [[X:%.*]])
+; LDEXP16-NEXT:    ret double [[LDEXP]]
+;
+; NOLDEXPF-LABEL: @test_simplify2(
+; NOLDEXPF-NEXT:    [[TMP1:%.*]] = sext i16 [[X:%.*]] to i32
+; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; NOLDEXPF-NEXT:    ret double [[LDEXP]]
+;
+; NOLDEXP-LABEL: @test_simplify2(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i16 [[X:%.*]] to double
+; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
+; NOLDEXP-NEXT:    ret double [[RET]]
+;
   %conv = sitofp i16 %x to double
   %ret = call double @exp2(double %conv)
-; CHECK: call double @ldexp
   ret double %ret
 }
 
 define double @test_simplify3(i8 signext %x) {
-; CHECK-LABEL: @test_simplify3(
+; LDEXP32-LABEL: @test_simplify3(
+; LDEXP32-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
+; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret double [[LDEXP]]
+;
+; LDEXP16-LABEL: @test_simplify3(
+; LDEXP16-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i16
+; LDEXP16-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i16 [[TMP1]])
+; LDEXP16-NEXT:    ret double [[LDEXP]]
+;
+; NOLDEXPF-LABEL: @test_simplify3(
+; NOLDEXPF-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
+; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; NOLDEXPF-NEXT:    ret double [[LDEXP]]
+;
+; NOLDEXP-LABEL: @test_simplify3(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i8 [[X:%.*]] to double
+; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
+; NOLDEXP-NEXT:    ret double [[RET]]
+;
   %conv = sitofp i8 %x to double
   %ret = call double @exp2(double %conv)
-; CHECK: call double @ldexp
   ret double %ret
 }
 
 define float @test_simplify4(i32 %x) {
-; CHECK-LABEL: @test_simplify4(
+; LDEXP32-LABEL: @test_simplify4(
+; LDEXP32-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[X:%.*]])
+; LDEXP32-NEXT:    ret float [[LDEXPF]]
+;
+; LDEXP16-LABEL: @test_simplify4(
+; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
+; LDEXP16-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]])
+; LDEXP16-NEXT:    ret float [[RET]]
+;
+; NOLDEXPF-LABEL: @test_simplify4(
+; NOLDEXPF-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
+; NOLDEXPF-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]])
+; NOLDEXPF-NEXT:    ret float [[RET]]
+;
+; NOLDEXP-LABEL: @test_simplify4(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
+; NOLDEXP-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]])
+; NOLDEXP-NEXT:    ret float [[RET]]
+;
   %conv = sitofp i32 %x to float
   %ret = call float @exp2f(float %conv)
-; CHECK: call float @ldexpf
   ret float %ret
 }
 
 ; Check exp2(uitofp(x)) -> ldexp(1.0, zext(x)).
 
 define double @test_no_simplify1(i32 %x) {
-; CHECK-LABEL: @test_no_simplify1(
+; LDEXP32-LABEL: @test_no_simplify1(
+; LDEXP32-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to double
+; LDEXP32-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
+; LDEXP32-NEXT:    ret double [[RET]]
+;
+; LDEXP16-LABEL: @test_no_simplify1(
+; LDEXP16-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to double
+; LDEXP16-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
+; LDEXP16-NEXT:    ret double [[RET]]
+;
+; NOLDEXPF-LABEL: @test_no_simplify1(
+; NOLDEXPF-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to double
+; NOLDEXPF-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
+; NOLDEXPF-NEXT:    ret double [[RET]]
+;
+; NOLDEXP-LABEL: @test_no_simplify1(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to double
+; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
+; NOLDEXP-NEXT:    ret double [[RET]]
+;
   %conv = uitofp i32 %x to double
   %ret = call double @exp2(double %conv)
-; CHECK: call double @exp2
   ret double %ret
 }
 
 define double @test_simplify6(i16 zeroext %x) {
-; CHECK-LABEL: @test_simplify6(
+; LDEXP32-LABEL: @test_simplify6(
+; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
+; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret double [[LDEXP]]
+;
+; LDEXP16-LABEL: @test_simplify6(
+; LDEXP16-NEXT:    [[CONV:%.*]] = uitofp i16 [[X:%.*]] to double
+; LDEXP16-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
+; LDEXP16-NEXT:    ret double [[RET]]
+;
+; NOLDEXPF-LABEL: @test_simplify6(
+; NOLDEXPF-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
+; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; NOLDEXPF-NEXT:    ret double [[LDEXP]]
+;
+; NOLDEXP-LABEL: @test_simplify6(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i16 [[X:%.*]] to double
+; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
+; NOLDEXP-NEXT:    ret double [[RET]]
+;
   %conv = uitofp i16 %x to double
   %ret = call double @exp2(double %conv)
-; CHECK: call double @ldexp
   ret double %ret
 }
 
 define double @test_simplify7(i8 zeroext %x) {
-; CHECK-LABEL: @test_simplify7(
+; LDEXP32-LABEL: @test_simplify7(
+; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
+; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret double [[LDEXP]]
+;
+; LDEXP16-LABEL: @test_simplify7(
+; LDEXP16-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16
+; LDEXP16-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i16 [[TMP1]])
+; LDEXP16-NEXT:    ret double [[LDEXP]]
+;
+; NOLDEXPF-LABEL: @test_simplify7(
+; NOLDEXPF-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
+; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; NOLDEXPF-NEXT:    ret double [[LDEXP]]
+;
+; NOLDEXP-LABEL: @test_simplify7(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i8 [[X:%.*]] to double
+; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
+; NOLDEXP-NEXT:    ret double [[RET]]
+;
   %conv = uitofp i8 %x to double
   %ret = call double @exp2(double %conv)
-; CHECK: call double @ldexp
   ret double %ret
 }
 
 define float @test_simplify8(i8 zeroext %x) {
-; CHECK-LABEL: @test_simplify8(
+; LDEXP32-LABEL: @test_simplify8(
+; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
+; LDEXP32-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret float [[LDEXPF]]
+;
+; LDEXP16-LABEL: @test_simplify8(
+; LDEXP16-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16
+; LDEXP16-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i16 [[TMP1]])
+; LDEXP16-NEXT:    ret float [[LDEXPF]]
+;
+; NOLDEXPF-LABEL: @test_simplify8(
+; NOLDEXPF-NEXT:    [[CONV:%.*]] = uitofp i8 [[X:%.*]] to float
+; NOLDEXPF-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]])
+; NOLDEXPF-NEXT:    ret float [[RET]]
+;
+; NOLDEXP-LABEL: @test_simplify8(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i8 [[X:%.*]] to float
+; NOLDEXP-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]])
+; NOLDEXP-NEXT:    ret float [[RET]]
+;
   %conv = uitofp i8 %x to float
   %ret = call float @exp2f(float %conv)
-; CHECK: call float @ldexpf
   ret float %ret
 }
 
@@ -81,19 +223,53 @@ declare double @llvm.exp2.f64(double)
 declare float @llvm.exp2.f32(float)
 
 define double @test_simplify9(i8 zeroext %x) {
-; INTRINSIC-LABEL: @test_simplify9(
+; LDEXP32-LABEL: @test_simplify9(
+; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
+; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret double [[LDEXP]]
+;
+; LDEXP16-LABEL: @test_simplify9(
+; LDEXP16-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16
+; LDEXP16-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i16 [[TMP1]])
+; LDEXP16-NEXT:    ret double [[LDEXP]]
+;
+; NOLDEXPF-LABEL: @test_simplify9(
+; NOLDEXPF-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
+; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; NOLDEXPF-NEXT:    ret double [[LDEXP]]
+;
+; NOLDEXP-LABEL: @test_simplify9(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i8 [[X:%.*]] to double
+; NOLDEXP-NEXT:    [[RET:%.*]] = call double @llvm.exp2.f64(double [[CONV]])
+; NOLDEXP-NEXT:    ret double [[RET]]
+;
   %conv = uitofp i8 %x to double
   %ret = call double @llvm.exp2.f64(double %conv)
-; LDEXP: call double @ldexp
-; NOLDEXP-NOT: call double @ldexp
   ret double %ret
 }
 
 define float @test_simplify10(i8 zeroext %x) {
-; INTRINSIC-LABEL: @test_simplify10(
+; LDEXP32-LABEL: @test_simplify10(
+; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
+; LDEXP32-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret float [[LDEXPF]]
+;
+; LDEXP16-LABEL: @test_simplify10(
+; LDEXP16-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16
+; LDEXP16-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i16 [[TMP1]])
+; LDEXP16-NEXT:    ret float [[LDEXPF]]
+;
+; NOLDEXPF-LABEL: @test_simplify10(
+; NOLDEXPF-NEXT:    [[CONV:%.*]] = uitofp i8 [[X:%.*]] to float
+; NOLDEXPF-NEXT:    [[RET:%.*]] = call float @llvm.exp2.f32(float [[CONV]])
+; NOLDEXPF-NEXT:    ret float [[RET]]
+;
+; NOLDEXP-LABEL: @test_simplify10(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i8 [[X:%.*]] to float
+; NOLDEXP-NEXT:    [[RET:%.*]] = call float @llvm.exp2.f32(float [[CONV]])
+; NOLDEXP-NEXT:    ret float [[RET]]
+;
   %conv = uitofp i8 %x to float
   %ret = call float @llvm.exp2.f32(float %conv)
-; LDEXPF: call float @ldexpf
-; NOLDEXPF-NOT: call float @ldexpf
   ret float %ret
 }

diff  --git a/llvm/test/Transforms/InstCombine/pow_fp_int.ll b/llvm/test/Transforms/InstCombine/pow_fp_int.ll
index 48297589ad91e..e0e13c642ba63 100644
--- a/llvm/test/Transforms/InstCombine/pow_fp_int.ll
+++ b/llvm/test/Transforms/InstCombine/pow_fp_int.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -instcombine -S < %s | FileCheck %s
+; RUN: opt -mtriple unknown -instcombine -S < %s | FileCheck %s
 
 ; PR42190
 

diff  --git a/llvm/test/Transforms/InstCombine/simplify-libcalls.ll b/llvm/test/Transforms/InstCombine/simplify-libcalls.ll
index d212bcd8ff767..25b168515cb82 100644
--- a/llvm/test/Transforms/InstCombine/simplify-libcalls.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-libcalls.ll
@@ -1,4 +1,5 @@
-; RUN: opt -S < %s -instcombine -instcombine-infinite-loop-threshold=2 | FileCheck %s
+; RUN: opt -S < %s -mtriple=unknown -instcombine -instcombine-infinite-loop-threshold=2 | FileCheck -check-prefixes=CHECK,CHECK32 %s
+; RUN: opt -S < %s -mtriple=msp430 -instcombine -instcombine-infinite-loop-threshold=2 | FileCheck -check-prefixes=CHECK,CHECK16 %s
 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32"
 
 @G = constant [3 x i8] c"%s\00"		; <[3 x i8]*> [#uses=1]
@@ -188,14 +189,33 @@ define double @fake_exp2(double %x) {
   ret double %y
 }
 define double @fake_ldexp(i32 %x) {
-; CHECK-LABEL: @fake_ldexp(
-; CHECK-NEXT:    [[Z:%.*]] = call double @ldexp(double 1.0{{.*}}, i32 %x)
-; CHECK-NEXT:    ret double [[Z]]
+; CHECK32-LABEL: @fake_ldexp(
+; CHECK32-NEXT:    [[Z:%.*]] = call double @ldexp(double 1.0{{.*}}, i32 %x)
+; CHECK32-NEXT:    ret double [[Z]]
+
+; CHECK16-LABEL: @fake_ldexp(
+; CHECK16-NEXT:    [[Y:%.*]] = sitofp i32 %x to double
+; CHECK16-NEXT:    [[Z:%.*]] = call inreg double @exp2(double [[Y]])
+; CHECK16-NEXT:    ret double [[Z]]
 
   %y = sitofp i32 %x to double
   %z = call inreg double @exp2(double %y)
   ret double %z
 }
+define double @fake_ldexp_16(i16 %x) {
+; CHECK32-LABEL: @fake_ldexp_16(
+; CHECK32-NEXT:    [[Y:%.*]] = sext i16 %x to i32
+; CHECK32-NEXT:    [[Z:%.*]] = call double @ldexp(double 1.0{{.*}}, i32 [[Y]])
+; CHECK32-NEXT:    ret double [[Z]]
+
+; CHECK16-LABEL: @fake_ldexp_16(
+; CHECK16-NEXT:    [[Z:%.*]] = call double @ldexp(double 1.0{{.*}}, i16 %x)
+; CHECK16-NEXT:    ret double [[Z]]
+
+  %y = sitofp i16 %x to double
+  %z = call inreg double @exp2(double %y)
+  ret double %z
+}
 
 
 attributes #0 = { nobuiltin }


        


More information about the llvm-commits mailing list