; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; Test that the exp2 library call simplifier works correctly. ; ; RUN: opt < %s -passes=instcombine -S -mtriple=unknown | FileCheck %s -check-prefixes=LDEXP32 ; RUN: opt < %s -passes=instcombine -S -mtriple=msp430 | FileCheck %s -check-prefixes=LDEXP16 ; RUN: opt < %s -passes=instcombine -S -mtriple=i386-pc-win32 | FileCheck %s -check-prefixes=NOLDEXPF ; RUN: opt < %s -passes=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" declare double @exp2(double) declare float @exp2f(float) ; Check exp2(sitofp(x)) -> ldexp(1.0, sext(x)). define double @test_simplify1(i32 %x) { ; 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) ret double %ret } define double @test_simplify2(i16 signext %x) { ; 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) ret double %ret } define double @test_simplify3(i8 signext %x) { ; 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) ret double %ret } define float @test_simplify4(i32 %x) { ; 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) ret float %ret } ; Check exp2(uitofp(x)) -> ldexp(1.0, zext(x)). define double @test_no_simplify1(i32 %x) { ; 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) ret double %ret } define double @test_simplify6(i16 zeroext %x) { ; 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) ret double %ret } define double @test_simplify7(i8 zeroext %x) { ; 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) ret double %ret } define float @test_simplify8(i8 zeroext %x) { ; 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) ret float %ret } declare double @llvm.exp2.f64(double) declare float @llvm.exp2.f32(float) define double @test_simplify9(i8 zeroext %x) { ; 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) ret double %ret } define float @test_simplify10(i8 zeroext %x) { ; 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) ret float %ret }