407 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -S -passes='simplifycfg<hoist-common-insts>' -mtriple=amdgcn-- --fp-contract=fast -mcpu=gfx1030 < %s | FileCheck -check-prefix=GFX -check-prefix=FP-CONTRACT-FAST %s3; RUN: opt -S -passes='simplifycfg<hoist-common-insts>' -mtriple=amdgcn-- --fp-contract=off -mcpu=gfx1030 < %s | FileCheck -check-prefix=GFX -check-prefix=UNSAFE-FP-MATH %s4; RUN: opt -S -passes='simplifycfg<hoist-common-insts>' -mtriple=amdgcn-- --fp-contract=off -mcpu=gfx1030 < %s | FileCheck -check-prefix=GFX -check-prefix=NO-UNSAFE-FP-MATH %s5 6define double @is_profitable_f64_contract(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {7; GFX-LABEL: define double @is_profitable_f64_contract(8; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0:[0-9]+]] {9; GFX-NEXT: [[ENTRY:.*:]]10; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 811; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+0012; GFX-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 813; GFX-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 814; GFX-NEXT: [[MUL:%.*]] = fmul contract double [[X]], [[A_1]]15; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]16; GFX: [[COMMON_RET:.*]]:17; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]18; GFX-NEXT: ret double [[COMMON_RET_OP]]19; GFX: [[IF_THEN]]:20; GFX-NEXT: [[ADD]] = fadd contract double 1.000000e+00, [[MUL]]21; GFX-NEXT: br label %[[COMMON_RET]]22; GFX: [[IF_ELSE]]:23; GFX-NEXT: [[SUB]] = fsub contract double [[MUL]], [[Y]]24; GFX-NEXT: br label %[[COMMON_RET]]25;26entry:27 %y = load double, ptr %ptr_y, align 828 %cmp = fcmp oeq double %y, 0.000000e+0029 %x = load double, ptr %ptr_x, align 830 br i1 %cmp, label %if.then, label %if.else31 32if.then: ; preds = %entry33 %a_1 = load double, ptr %ptr_a, align 834 %mul = fmul contract double %x, %a_135 %add = fadd contract double 1.000000e+00, %mul36 ret double %add37 38if.else: ; preds = %entry39 %a_2 = load double, ptr %ptr_a, align 840 %mul1 = fmul contract double %x, %a_241 %sub = fsub contract double %mul1, %y42 ret double %sub43}44 45define double @is_profitable_f64_modifiers(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {46; GFX-LABEL: define double @is_profitable_f64_modifiers(47; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] {48; GFX-NEXT: [[ENTRY:.*:]]49; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 850; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+0051; GFX-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 852; GFX-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 853; GFX-NEXT: [[MUL:%.*]] = fmul contract double [[X]], [[A_1]]54; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]55; GFX: [[COMMON_RET:.*]]:56; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]57; GFX-NEXT: ret double [[COMMON_RET_OP]]58; GFX: [[IF_THEN]]:59; GFX-NEXT: [[FNEG:%.*]] = fneg double [[MUL]]60; GFX-NEXT: [[ADD]] = fadd contract double 1.000000e+00, [[FNEG]]61; GFX-NEXT: br label %[[COMMON_RET]]62; GFX: [[IF_ELSE]]:63; GFX-NEXT: [[FABS:%.*]] = call double @llvm.fabs.f64(double [[MUL]])64; GFX-NEXT: [[SUB]] = fsub contract double [[FABS]], [[Y]]65; GFX-NEXT: br label %[[COMMON_RET]]66;67entry:68 %y = load double, ptr %ptr_y, align 869 %cmp = fcmp oeq double %y, 0.000000e+0070 %x = load double, ptr %ptr_x, align 871 br i1 %cmp, label %if.then, label %if.else72 73if.then: ; preds = %entry74 %a_1 = load double, ptr %ptr_a, align 875 %mul = fmul contract double %x, %a_176 %fneg = fneg double %mul77 %add = fadd contract double 1.000000e+00, %fneg78 ret double %add79 80if.else: ; preds = %entry81 %a_2 = load double, ptr %ptr_a, align 882 %mul1 = fmul contract double %x, %a_283 %fabs = call double @llvm.fabs.f64(double %mul1)84 %sub = fsub contract double %fabs, %y85 ret double %sub86}87 88define float @is_profitable_f32(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {89; GFX-LABEL: define float @is_profitable_f32(90; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] {91; GFX-NEXT: [[ENTRY:.*:]]92; GFX-NEXT: [[Y:%.*]] = load float, ptr [[PTR_Y]], align 893; GFX-NEXT: [[CMP:%.*]] = fcmp oeq float [[Y]], 0.000000e+0094; GFX-NEXT: [[X:%.*]] = load float, ptr [[PTR_X]], align 895; GFX-NEXT: [[A_1:%.*]] = load float, ptr [[PTR_A]], align 896; GFX-NEXT: [[MUL:%.*]] = fmul contract float [[X]], [[A_1]]97; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]98; GFX: [[COMMON_RET:.*]]:99; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi float [ [[MUL]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]100; GFX-NEXT: ret float [[COMMON_RET_OP]]101; GFX: [[IF_THEN]]:102; GFX-NEXT: [[ADD:%.*]] = fadd contract float 1.000000e+00, [[MUL]]103; GFX-NEXT: br label %[[COMMON_RET]]104; GFX: [[IF_ELSE]]:105; GFX-NEXT: [[SUB]] = fsub contract float [[MUL]], [[Y]]106; GFX-NEXT: br label %[[COMMON_RET]]107;108entry:109 %y = load float, ptr %ptr_y, align 8110 %cmp = fcmp oeq float %y, 0.000000e+00111 %x = load float, ptr %ptr_x, align 8112 br i1 %cmp, label %if.then, label %if.else113 114 115if.then: ; preds = %entry116 %a_1 = load float, ptr %ptr_a, align 8117 %mul = fmul contract float %x, %a_1118 %add = fadd contract float 1.000000e+00, %mul119 ret float %mul120 121if.else: ; preds = %entry122 %a_2 = load float, ptr %ptr_a, align 8123 %mul1 = fmul contract float %x, %a_2124 %sub = fsub contract float %mul1, %y125 ret float %sub126}127 128define half @is_profitable_f16_preserve(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {129; GFX-LABEL: define half @is_profitable_f16_preserve(130; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] {131; GFX-NEXT: [[ENTRY:.*:]]132; GFX-NEXT: [[Y:%.*]] = load half, ptr [[PTR_Y]], align 8133; GFX-NEXT: [[CMP:%.*]] = fcmp oeq half [[Y]], 0xH0000134; GFX-NEXT: [[X:%.*]] = load half, ptr [[PTR_X]], align 8135; GFX-NEXT: [[A_1:%.*]] = load half, ptr [[PTR_A]], align 8136; GFX-NEXT: [[MUL:%.*]] = fmul contract half [[X]], [[A_1]]137; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]138; GFX: [[COMMON_RET:.*]]:139; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi half [ [[MUL]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]140; GFX-NEXT: ret half [[COMMON_RET_OP]]141; GFX: [[IF_THEN]]:142; GFX-NEXT: [[ADD:%.*]] = fadd contract half [[Y]], [[MUL]]143; GFX-NEXT: br label %[[COMMON_RET]]144; GFX: [[IF_ELSE]]:145; GFX-NEXT: [[SUB]] = fsub contract half [[MUL]], [[Y]]146; GFX-NEXT: br label %[[COMMON_RET]]147;148entry:149 %y = load half, ptr %ptr_y, align 8150 %cmp = fcmp oeq half %y, 0.000000e+00151 %x = load half, ptr %ptr_x, align 8152 br i1 %cmp, label %if.then, label %if.else153 154if.then: ; preds = %entry155 %a_1 = load half, ptr %ptr_a, align 8156 %mul = fmul contract half %x, %a_1157 %add = fadd contract half %y, %mul158 ret half %mul159 160if.else: ; preds = %entry161 %a_2 = load half, ptr %ptr_a, align 8162 %mul1 = fmul contract half %x, %a_2163 %sub = fsub contract half %mul1, %y164 ret half %sub165}166 167define half @is_profitable_f16_ieee(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #1 {168; GFX-LABEL: define half @is_profitable_f16_ieee(169; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR1:[0-9]+]] {170; GFX-NEXT: [[ENTRY:.*:]]171; GFX-NEXT: [[Y:%.*]] = load half, ptr [[PTR_Y]], align 8172; GFX-NEXT: [[CMP:%.*]] = fcmp oeq half [[Y]], 0xH0000173; GFX-NEXT: [[X:%.*]] = load half, ptr [[PTR_X]], align 8174; GFX-NEXT: [[A_1:%.*]] = load half, ptr [[PTR_A]], align 8175; GFX-NEXT: [[MUL:%.*]] = fmul contract half [[X]], [[A_1]]176; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]177; GFX: [[COMMON_RET:.*]]:178; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi half [ [[MUL]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]179; GFX-NEXT: ret half [[COMMON_RET_OP]]180; GFX: [[IF_THEN]]:181; GFX-NEXT: [[ADD:%.*]] = fadd contract half [[Y]], [[MUL]]182; GFX-NEXT: br label %[[COMMON_RET]]183; GFX: [[IF_ELSE]]:184; GFX-NEXT: [[SUB]] = fsub contract half [[MUL]], [[Y]]185; GFX-NEXT: br label %[[COMMON_RET]]186;187entry:188 %y = load half, ptr %ptr_y, align 8189 %cmp = fcmp oeq half %y, 0.000000e+00190 %x = load half, ptr %ptr_x, align 8191 br i1 %cmp, label %if.then, label %if.else192 193if.then: ; preds = %entry194 %a_1 = load half, ptr %ptr_a, align 8195 %mul = fmul contract half %x, %a_1196 %add = fadd contract half %y, %mul197 ret half %mul198 199if.else: ; preds = %entry200 %a_2 = load half, ptr %ptr_a, align 8201 %mul1 = fmul contract half %x, %a_2202 %sub = fsub contract half %mul1, %y203 ret half %sub204}205 206define bfloat @is_profitable_bfloat_preserve(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {207; GFX-LABEL: define bfloat @is_profitable_bfloat_preserve(208; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] {209; GFX-NEXT: [[ENTRY:.*:]]210; GFX-NEXT: [[Y:%.*]] = load bfloat, ptr [[PTR_Y]], align 8211; GFX-NEXT: [[CMP:%.*]] = fcmp oeq bfloat [[Y]], 0xR0000212; GFX-NEXT: [[X:%.*]] = load bfloat, ptr [[PTR_X]], align 8213; GFX-NEXT: [[A_1:%.*]] = load bfloat, ptr [[PTR_A]], align 8214; GFX-NEXT: [[MUL:%.*]] = fmul contract bfloat [[X]], [[A_1]]215; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]216; GFX: [[COMMON_RET:.*]]:217; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi bfloat [ [[MUL]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]218; GFX-NEXT: ret bfloat [[COMMON_RET_OP]]219; GFX: [[IF_THEN]]:220; GFX-NEXT: [[ADD:%.*]] = fadd contract bfloat 0xR3F80, [[MUL]]221; GFX-NEXT: br label %[[COMMON_RET]]222; GFX: [[IF_ELSE]]:223; GFX-NEXT: [[SUB]] = fsub contract bfloat [[MUL]], [[Y]]224; GFX-NEXT: br label %[[COMMON_RET]]225;226entry:227 %y = load bfloat, ptr %ptr_y, align 8228 %cmp = fcmp oeq bfloat %y, 0.000000e+00229 %x = load bfloat, ptr %ptr_x, align 8230 br i1 %cmp, label %if.then, label %if.else231 232if.then: ; preds = %entry233 %a_1 = load bfloat, ptr %ptr_a, align 8234 %mul = fmul contract bfloat %x, %a_1235 %add = fadd contract bfloat 1.000000e+00, %mul236 ret bfloat %mul237 238if.else: ; preds = %entry239 %a_2 = load bfloat, ptr %ptr_a, align 8240 %mul1 = fmul contract bfloat %x, %a_2241 %sub = fsub contract bfloat %mul1, %y242 ret bfloat %sub243}244 245define bfloat @is_profitable_bfloat_ieee(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #1 {246; GFX-LABEL: define bfloat @is_profitable_bfloat_ieee(247; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR1]] {248; GFX-NEXT: [[ENTRY:.*:]]249; GFX-NEXT: [[Y:%.*]] = load bfloat, ptr [[PTR_Y]], align 8250; GFX-NEXT: [[CMP:%.*]] = fcmp oeq bfloat [[Y]], 0xR0000251; GFX-NEXT: [[X:%.*]] = load bfloat, ptr [[PTR_X]], align 8252; GFX-NEXT: [[A_1:%.*]] = load bfloat, ptr [[PTR_A]], align 8253; GFX-NEXT: [[MUL:%.*]] = fmul contract bfloat [[X]], [[A_1]]254; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]255; GFX: [[COMMON_RET:.*]]:256; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi bfloat [ [[MUL]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]257; GFX-NEXT: ret bfloat [[COMMON_RET_OP]]258; GFX: [[IF_THEN]]:259; GFX-NEXT: [[ADD:%.*]] = fadd contract bfloat 0xR3F80, [[MUL]]260; GFX-NEXT: br label %[[COMMON_RET]]261; GFX: [[IF_ELSE]]:262; GFX-NEXT: [[SUB]] = fsub contract bfloat [[MUL]], [[Y]]263; GFX-NEXT: br label %[[COMMON_RET]]264;265entry:266 %y = load bfloat, ptr %ptr_y, align 8267 %cmp = fcmp oeq bfloat %y, 0.000000e+00268 %x = load bfloat, ptr %ptr_x, align 8269 br i1 %cmp, label %if.then, label %if.else270 271if.then: ; preds = %entry272 %a_1 = load bfloat, ptr %ptr_a, align 8273 %mul = fmul contract bfloat %x, %a_1274 %add = fadd contract bfloat 1.000000e+00, %mul275 ret bfloat %mul276 277if.else: ; preds = %entry278 %a_2 = load bfloat, ptr %ptr_a, align 8279 %mul1 = fmul contract bfloat %x, %a_2280 %sub = fsub contract bfloat %mul1, %y281 ret bfloat %sub282}283 284define double @is_profitable_constant(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #1 {285; GFX-LABEL: define double @is_profitable_constant(286; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR1]] {287; GFX-NEXT: [[ENTRY:.*:]]288; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8289; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00290; GFX-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8291; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]292; GFX: [[COMMON_RET:.*]]:293; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]294; GFX-NEXT: ret double [[COMMON_RET_OP]]295; GFX: [[IF_THEN]]:296; GFX-NEXT: [[MUL:%.*]] = fmul contract double 2.000000e+00, [[X]]297; GFX-NEXT: [[ADD]] = fadd contract double 1.000000e+00, [[MUL]]298; GFX-NEXT: br label %[[COMMON_RET]]299; GFX: [[IF_ELSE]]:300; GFX-NEXT: [[MUL1:%.*]] = fmul contract double 3.000000e+00, [[X]]301; GFX-NEXT: [[SUB]] = fsub contract double [[MUL1]], [[Y]]302; GFX-NEXT: br label %[[COMMON_RET]]303;304entry:305 %y = load double, ptr %ptr_y, align 8306 %cmp = fcmp oeq double %y, 0.000000e+00307 %x = load double, ptr %ptr_x, align 8308 br i1 %cmp, label %if.then, label %if.else309 310if.then: ; preds = %entry311 %mul = fmul contract double 2.000000e+00, %x312 %add = fadd contract double 1.000000e+00, %mul313 ret double %add314 315if.else: ; preds = %entry316 %mul1 = fmul contract double 3.000000e+00, %x317 %sub = fsub contract double %mul1, %y318 ret double %sub319}320 321@v1_ptr = external addrspace(3) global ptr322@v2_ptr = external addrspace(3) global ptr323 324define <8 x half> @is_profitable_vector(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) {325; GFX-LABEL: define <8 x half> @is_profitable_vector(326; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR2:[0-9]+]] {327; GFX-NEXT: [[ENTRY:.*:]]328; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8329; GFX-NEXT: [[X:%.*]] = load <8 x half>, ptr [[PTR_X]], align 8330; GFX-NEXT: [[V1:%.*]] = load <8 x half>, ptr addrspace(3) @v1_ptr, align 16331; GFX-NEXT: [[V2:%.*]] = load <8 x half>, ptr addrspace(3) @v2_ptr, align 16332; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00333; GFX-NEXT: [[MUL:%.*]] = fmul contract <8 x half> [[V1]], [[X]]334; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]335; GFX: [[COMMON_RET:.*]]:336; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi <8 x half> [ [[ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]337; GFX-NEXT: ret <8 x half> [[COMMON_RET_OP]]338; GFX: [[IF_THEN]]:339; GFX-NEXT: [[ADD]] = fadd contract <8 x half> [[V2]], [[MUL]]340; GFX-NEXT: br label %[[COMMON_RET]]341; GFX: [[IF_ELSE]]:342; GFX-NEXT: [[SUB]] = fsub contract <8 x half> [[MUL]], [[V2]]343; GFX-NEXT: br label %[[COMMON_RET]]344;345entry:346 %y = load double, ptr %ptr_y, align 8347 %x = load <8 x half>, ptr %ptr_x, align 8348 %v1 = load <8 x half>, ptr addrspace(3) @v1_ptr349 %v2 = load <8 x half>, ptr addrspace(3) @v2_ptr350 %cmp = fcmp oeq double %y, 0.000000e+00351 br i1 %cmp, label %if.then, label %if.else352 353if.then: ; preds = %entry354 %mul = fmul contract <8 x half> %v1, %x355 %add = fadd contract <8 x half> %v2, %mul356 ret <8 x half> %add357 358if.else: ; preds = %entry359 %mul1 = fmul contract <8 x half> %v1, %x360 %sub = fsub contract <8 x half> %mul1, %v2361 ret <8 x half> %sub362}363 364define double @is_profitable_f64_nocontract(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 {365; GFX-LABEL: define double @is_profitable_f64_nocontract(366; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] {367; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8368; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00369; GFX-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8370; GFX-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 8371; GFX-NEXT: [[MUL:%.*]] = fmul double [[X]], [[A_1]]372; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]373; GFX: [[COMMON_RET:.*]]:374; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[PTR_ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ]375; GFX-NEXT: ret double [[COMMON_RET_OP]]376; GFX: [[IF_THEN]]:377; GFX-NEXT: [[PTR_ADD]] = fadd double 1.000000e+00, [[MUL]]378; GFX-NEXT: br label %[[COMMON_RET]]379; GFX: [[IF_ELSE]]:380; GFX-NEXT: [[SUB]] = fsub double [[MUL]], [[Y]]381; GFX-NEXT: br label %[[COMMON_RET]]382;383 %y = load double, ptr %ptr_y, align 8384 %cmp = fcmp oeq double %y, 0.000000e+00385 %x = load double, ptr %ptr_x, align 8386 br i1 %cmp, label %if.then, label %if.else387 388if.then: ; preds = %entry389 %a_1 = load double, ptr %ptr_a, align 8390 %mul = fmul double %x, %a_1391 %ptr_add = fadd double 1.000000e+00, %mul392 ret double %ptr_add393 394if.else: ; preds = %entry395 %a_2 = load double, ptr %ptr_a, align 8396 %mul1 = fmul double %x, %a_2397 %sub = fsub double %mul1, %y398 ret double %sub399}400 401attributes #0 = { nounwind "denormal-fp-math"="preserve-sign,preserve-sign" }402attributes #1 = { nounwind "denormal-fp-math"="ieee,ieee" }403;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:404; FP-CONTRACT-FAST: {{.*}}405; NO-UNSAFE-FP-MATH: {{.*}}406; UNSAFE-FP-MATH: {{.*}}407