brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.7 KiB · 0b5d8b3 Raw
243 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define float @fadd_fpext_op0(float %x, double %y) {5; CHECK-LABEL: @fadd_fpext_op0(6; CHECK-NEXT:    [[EXT:%.*]] = fpext float [[X:%.*]] to double7; CHECK-NEXT:    [[BO:%.*]] = fadd reassoc double [[Y:%.*]], [[EXT]]8; CHECK-NEXT:    [[R:%.*]] = fptrunc double [[BO]] to float9; CHECK-NEXT:    ret float [[R]]10;11  %ext = fpext float %x to double12  %bo = fadd reassoc double %ext, %y13  %r = fptrunc double %bo to float14  ret float %r15}16 17define half @fsub_fpext_op1(half %x, double %y) {18; CHECK-LABEL: @fsub_fpext_op1(19; CHECK-NEXT:    [[EXT:%.*]] = fpext half [[X:%.*]] to double20; CHECK-NEXT:    [[BO:%.*]] = fsub reassoc double [[Y:%.*]], [[EXT]]21; CHECK-NEXT:    [[R:%.*]] = fptrunc double [[BO]] to half22; CHECK-NEXT:    ret half [[R]]23;24  %ext = fpext half %x to double25  %bo = fsub reassoc double %y, %ext26  %r = fptrunc double %bo to half27  ret half %r28}29 30define <2 x float> @fdiv_constant_op0(<2 x double> %x) {31; CHECK-LABEL: @fdiv_constant_op0(32; CHECK-NEXT:    [[BO:%.*]] = fdiv reassoc <2 x double> <double 4.210000e+01, double -1.000000e-01>, [[X:%.*]]33; CHECK-NEXT:    [[R:%.*]] = fptrunc <2 x double> [[BO]] to <2 x float>34; CHECK-NEXT:    ret <2 x float> [[R]]35;36  %bo = fdiv reassoc <2 x double> <double 42.1, double -0.1>, %x37  %r = fptrunc <2 x double> %bo to <2 x float>38  ret <2 x float> %r39}40 41define <2 x half> @fmul_constant_op1(<2 x float> %x) {42; CHECK-LABEL: @fmul_constant_op1(43; CHECK-NEXT:    [[BO:%.*]] = fmul reassoc <2 x float> [[X:%.*]], <float 0x47EFFFFFE0000000, float 5.000000e-01>44; CHECK-NEXT:    [[R:%.*]] = fptrunc <2 x float> [[BO]] to <2 x half>45; CHECK-NEXT:    ret <2 x half> [[R]]46;47  %bo = fmul reassoc <2 x float> %x, <float 0x47efffffe0000000, float 0.5>48  %r = fptrunc <2 x float> %bo to <2 x half>49  ret <2 x half> %r50}51 52define float @fptrunc_select_true_val(float %x, double %y, i1 %cond) {53; CHECK-LABEL: @fptrunc_select_true_val(54; CHECK-NEXT:    [[TMP1:%.*]] = fptrunc double [[Y:%.*]] to float55; CHECK-NEXT:    [[NARROW_SEL:%.*]] = select i1 [[COND:%.*]], float [[TMP1]], float [[X:%.*]]56; CHECK-NEXT:    ret float [[NARROW_SEL]]57;58  %e = fpext float %x to double59  %sel = select fast i1 %cond, double %y, double %e60  %r = fptrunc double %sel to float61  ret float %r62}63 64define float @fptrunc_fast_select_true_val(float %x, double %y, i1 %cond) {65; CHECK-LABEL: @fptrunc_fast_select_true_val(66; CHECK-NEXT:    [[TMP1:%.*]] = fptrunc fast double [[Y:%.*]] to float67; CHECK-NEXT:    [[NARROW_SEL:%.*]] = select i1 [[COND:%.*]], float [[TMP1]], float [[X:%.*]]68; CHECK-NEXT:    ret float [[NARROW_SEL]]69;70  %e = fpext float %x to double71  %sel = select fast i1 %cond, double %y, double %e72  %r = fptrunc fast double %sel to float73  ret float %r74}75 76define <2 x float> @fptrunc_select_false_val(<2 x float> %x, <2 x double> %y, <2 x i1> %cond) {77; CHECK-LABEL: @fptrunc_select_false_val(78; CHECK-NEXT:    [[TMP1:%.*]] = fptrunc <2 x double> [[Y:%.*]] to <2 x float>79; CHECK-NEXT:    [[NARROW_SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x float> [[TMP1]]80; CHECK-NEXT:    ret <2 x float> [[NARROW_SEL]]81;82  %e = fpext <2 x float> %x to <2 x double>83  %sel = select nnan <2 x i1> %cond, <2 x double> %e, <2 x double> %y84  %r = fptrunc <2 x double> %sel to <2 x float>85  ret <2 x float> %r86}87 88define <2 x float> @fptrunc_nnan_select_false_val(<2 x float> %x, <2 x double> %y, <2 x i1> %cond) {89; CHECK-LABEL: @fptrunc_nnan_select_false_val(90; CHECK-NEXT:    [[TMP1:%.*]] = fptrunc nnan <2 x double> [[Y:%.*]] to <2 x float>91; CHECK-NEXT:    [[NARROW_SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x float> [[TMP1]]92; CHECK-NEXT:    ret <2 x float> [[NARROW_SEL]]93;94  %e = fpext <2 x float> %x to <2 x double>95  %sel = select nnan <2 x i1> %cond, <2 x double> %e, <2 x double> %y96  %r = fptrunc nnan <2 x double> %sel to <2 x float>97  ret <2 x float> %r98}99 100declare void @use(float)101 102define half @fptrunc_select_true_val_extra_use(half %x, float %y, i1 %cond) {103; CHECK-LABEL: @fptrunc_select_true_val_extra_use(104; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to float105; CHECK-NEXT:    call void @use(float [[E]])106; CHECK-NEXT:    [[TMP1:%.*]] = fptrunc float [[Y:%.*]] to half107; CHECK-NEXT:    [[NARROW_SEL:%.*]] = select i1 [[COND:%.*]], half [[TMP1]], half [[X]]108; CHECK-NEXT:    ret half [[NARROW_SEL]]109;110  %e = fpext half %x to float111  call void @use(float %e)112  %sel = select ninf i1 %cond, float %y, float %e113  %r = fptrunc float %sel to half114  ret half %r115}116 117define half @fptrunc_max(half %arg) {118; CHECK-LABEL: @fptrunc_max(119; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt half [[ARG:%.*]], 0xH0000120; CHECK-NEXT:    [[NARROW_SEL:%.*]] = select i1 [[CMP]], half 0xH0000, half [[ARG]]121; CHECK-NEXT:    ret half [[NARROW_SEL]]122;123  %ext = fpext half %arg to double124  %cmp = fcmp olt double %ext, 0.000000e+00125  %max = select i1 %cmp, double 0.000000e+00, double %ext126  %trunc = fptrunc double %max to half127  ret half %trunc128}129 130; Negative test - this would require an extra instruction.131 132define half @fptrunc_select_true_val_extra_use_2(half %x, float %y, i1 %cond) {133; CHECK-LABEL: @fptrunc_select_true_val_extra_use_2(134; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to float135; CHECK-NEXT:    [[SEL:%.*]] = select ninf i1 [[COND:%.*]], float [[Y:%.*]], float [[E]]136; CHECK-NEXT:    call void @use(float [[SEL]])137; CHECK-NEXT:    [[R:%.*]] = fptrunc float [[SEL]] to half138; CHECK-NEXT:    ret half [[R]]139;140  %e = fpext half %x to float141  %sel = select ninf i1 %cond, float %y, float %e142  call void @use(float %sel)143  %r = fptrunc float %sel to half144  ret half %r145}146 147; Negative test - the extend must be from the same source type as the result of the trunc.148 149define float @fptrunc_select_true_val_type_mismatch(half %x, double %y, i1 %cond) {150; CHECK-LABEL: @fptrunc_select_true_val_type_mismatch(151; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to double152; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], double [[Y:%.*]], double [[E]]153; CHECK-NEXT:    [[R:%.*]] = fptrunc double [[SEL]] to float154; CHECK-NEXT:    ret float [[R]]155;156  %e = fpext half %x to double157  %sel = select i1 %cond, double %y, double %e158  %r = fptrunc double %sel to float159  ret float %r160}161 162; Negative test - but given enough FMF, should this be folded?163 164define float @fptrunc_select_true_val_type_mismatch_fast(half %x, double %y, i1 %cond) {165; CHECK-LABEL: @fptrunc_select_true_val_type_mismatch_fast(166; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to double167; CHECK-NEXT:    [[SEL:%.*]] = select fast i1 [[COND:%.*]], double [[Y:%.*]], double [[E]]168; CHECK-NEXT:    [[R:%.*]] = fptrunc double [[SEL]] to float169; CHECK-NEXT:    ret float [[R]]170;171  %e = fpext half %x to double172  %sel = select fast i1 %cond, double %y, double %e173  %r = fptrunc double %sel to float174  ret float %r175}176 177; Convert from integer is exact, so convert directly to float.178 179define <2 x float> @ItoFtoF_s54_f64_f32(<2 x i54> %i) {180; CHECK-LABEL: @ItoFtoF_s54_f64_f32(181; CHECK-NEXT:    [[R:%.*]] = sitofp <2 x i54> [[I:%.*]] to <2 x float>182; CHECK-NEXT:    ret <2 x float> [[R]]183;184  %x = sitofp <2 x i54> %i to <2 x double>185  %r = fptrunc <2 x double> %x to <2 x float>186  ret <2 x float> %r187}188 189; Convert from integer is exact, so convert directly to half.190; Extra use is ok.191 192define half @ItoFtoF_u24_f32_f16(i24 %i) {193; CHECK-LABEL: @ItoFtoF_u24_f32_f16(194; CHECK-NEXT:    [[X:%.*]] = uitofp i24 [[I:%.*]] to float195; CHECK-NEXT:    call void @use(float [[X]])196; CHECK-NEXT:    [[R:%.*]] = uitofp i24 [[I]] to half197; CHECK-NEXT:    ret half [[R]]198;199  %x = uitofp i24 %i to float200  call void @use(float %x)201  %r = fptrunc float %x to half202  ret half %r203}204 205; Negative test - intermediate rounding in float type.206 207define float @ItoFtoF_s55_f64_f32(i55 %i) {208; CHECK-LABEL: @ItoFtoF_s55_f64_f32(209; CHECK-NEXT:    [[X:%.*]] = sitofp i55 [[I:%.*]] to double210; CHECK-NEXT:    [[R:%.*]] = fptrunc double [[X]] to float211; CHECK-NEXT:    ret float [[R]]212;213  %x = sitofp i55 %i to double214  %r = fptrunc double %x to float215  ret float %r216}217 218; Negative test - intermediate rounding in float type.219 220define half @ItoFtoF_u25_f32_f16(i25 %i) {221; CHECK-LABEL: @ItoFtoF_u25_f32_f16(222; CHECK-NEXT:    [[X:%.*]] = uitofp i25 [[I:%.*]] to float223; CHECK-NEXT:    [[R:%.*]] = fptrunc float [[X]] to half224; CHECK-NEXT:    ret half [[R]]225;226  %x = uitofp i25 %i to float227  %r = fptrunc float %x to half228  ret half %r229}230 231; Negative test - bitcast bfloat to half is not optimized232 233define half @fptrunc_to_bfloat_bitcast_to_half(float %src) {234; CHECK-LABEL: @fptrunc_to_bfloat_bitcast_to_half(235; CHECK-NEXT:    [[TRUNC:%.*]] = fptrunc float [[SRC:%.*]] to bfloat236; CHECK-NEXT:    [[CAST:%.*]] = bitcast bfloat [[TRUNC]] to half237; CHECK-NEXT:    ret half [[CAST]]238;239  %trunc = fptrunc float %src to bfloat240  %cast = bitcast bfloat %trunc to half241  ret half %cast242}243