1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; 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 %s 3; RUN: opt -S -passes='simplifycfg<hoist-common-insts>' -mtriple=amdgcn-- --fp-contract=off --enable-unsafe-fp-math -mcpu=gfx1030 < %s | FileCheck -check-prefix=GFX -check-prefix=UNSAFE-FP-MATH %s 4; 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 %s 5 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 8 11; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00 12; GFX-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8 13; GFX-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 8 14; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] 15; GFX: [[COMMON_RET:.*]]: 16; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ] 17; GFX-NEXT: ret double [[COMMON_RET_OP]] 18; GFX: [[IF_THEN]]: 19; GFX-NEXT: [[MUL:%.*]] = fmul contract double [[X]], [[A_1]] 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: [[MUL1:%.*]] = fmul contract double [[X]], [[A_1]] 24; GFX-NEXT: [[SUB]] = fsub contract double [[MUL1]], [[Y]] 25; GFX-NEXT: br label %[[COMMON_RET]] 26; 27entry: 28 %y = load double, ptr %ptr_y, align 8 29 %cmp = fcmp oeq double %y, 0.000000e+00 30 %x = load double, ptr %ptr_x, align 8 31 br i1 %cmp, label %if.then, label %if.else 32 33if.then: ; preds = %entry 34 %a_1 = load double, ptr %ptr_a, align 8 35 %mul = fmul contract double %x, %a_1 36 %add = fadd contract double 1.000000e+00, %mul 37 ret double %add 38 39if.else: ; preds = %entry 40 %a_2 = load double, ptr %ptr_a, align 8 41 %mul1 = fmul contract double %x, %a_2 42 %sub = fsub contract double %mul1, %y 43 ret double %sub 44} 45 46define double @is_profitable_f64_modifiers(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 { 47; GFX-LABEL: define double @is_profitable_f64_modifiers( 48; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] { 49; GFX-NEXT: [[ENTRY:.*:]] 50; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8 51; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00 52; GFX-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8 53; GFX-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 8 54; GFX-NEXT: [[MUL:%.*]] = fmul contract double [[X]], [[A_1]] 55; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] 56; GFX: [[COMMON_RET:.*]]: 57; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ] 58; GFX-NEXT: ret double [[COMMON_RET_OP]] 59; GFX: [[IF_THEN]]: 60; GFX-NEXT: [[FNEG:%.*]] = fneg double [[MUL]] 61; GFX-NEXT: [[ADD]] = fadd contract double 1.000000e+00, [[FNEG]] 62; GFX-NEXT: br label %[[COMMON_RET]] 63; GFX: [[IF_ELSE]]: 64; GFX-NEXT: [[FABS:%.*]] = call double @llvm.fabs.f64(double [[MUL]]) 65; GFX-NEXT: [[SUB]] = fsub contract double [[FABS]], [[Y]] 66; GFX-NEXT: br label %[[COMMON_RET]] 67; 68entry: 69 %y = load double, ptr %ptr_y, align 8 70 %cmp = fcmp oeq double %y, 0.000000e+00 71 %x = load double, ptr %ptr_x, align 8 72 br i1 %cmp, label %if.then, label %if.else 73 74if.then: ; preds = %entry 75 %a_1 = load double, ptr %ptr_a, align 8 76 %mul = fmul contract double %x, %a_1 77 %fneg = fneg double %mul 78 %add = fadd contract double 1.000000e+00, %fneg 79 ret double %add 80 81if.else: ; preds = %entry 82 %a_2 = load double, ptr %ptr_a, align 8 83 %mul1 = fmul contract double %x, %a_2 84 %fabs = call double @llvm.fabs.f64(double %mul1) 85 %sub = fsub contract double %fabs, %y 86 ret double %sub 87} 88 89define float @is_profitable_f32(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 { 90; GFX-LABEL: define float @is_profitable_f32( 91; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] { 92; GFX-NEXT: [[ENTRY:.*:]] 93; GFX-NEXT: [[Y:%.*]] = load float, ptr [[PTR_Y]], align 8 94; GFX-NEXT: [[CMP:%.*]] = fcmp oeq float [[Y]], 0.000000e+00 95; GFX-NEXT: [[X:%.*]] = load float, ptr [[PTR_X]], align 8 96; GFX-NEXT: [[A_1:%.*]] = load float, ptr [[PTR_A]], align 8 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: [[MUL]] = fmul contract float [[X]], [[A_1]] 103; GFX-NEXT: [[ADD:%.*]] = fadd contract float 1.000000e+00, [[MUL]] 104; GFX-NEXT: br label %[[COMMON_RET]] 105; GFX: [[IF_ELSE]]: 106; GFX-NEXT: [[MUL1:%.*]] = fmul contract float [[X]], [[A_1]] 107; GFX-NEXT: [[SUB]] = fsub contract float [[MUL1]], [[Y]] 108; GFX-NEXT: br label %[[COMMON_RET]] 109; 110entry: 111 %y = load float, ptr %ptr_y, align 8 112 %cmp = fcmp oeq float %y, 0.000000e+00 113 %x = load float, ptr %ptr_x, align 8 114 br i1 %cmp, label %if.then, label %if.else 115 116if.then: ; preds = %entry 117 %a_1 = load float, ptr %ptr_a, align 8 118 %mul = fmul contract float %x, %a_1 119 %add = fadd contract float 1.000000e+00, %mul 120 ret float %mul 121 122if.else: ; preds = %entry 123 %a_2 = load float, ptr %ptr_a, align 8 124 %mul1 = fmul contract float %x, %a_2 125 %sub = fsub contract float %mul1, %y 126 ret float %sub 127} 128 129define half @is_profitable_f16_preserve(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 { 130; GFX-LABEL: define half @is_profitable_f16_preserve( 131; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] { 132; GFX-NEXT: [[ENTRY:.*:]] 133; GFX-NEXT: [[Y:%.*]] = load half, ptr [[PTR_Y]], align 8 134; GFX-NEXT: [[CMP:%.*]] = fcmp oeq half [[Y]], 0xH0000 135; GFX-NEXT: [[X:%.*]] = load half, ptr [[PTR_X]], align 8 136; GFX-NEXT: [[A_1:%.*]] = load half, ptr [[PTR_A]], align 8 137; GFX-NEXT: [[MUL:%.*]] = fmul contract half [[X]], [[A_1]] 138; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] 139; GFX: [[COMMON_RET:.*]]: 140; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi half [ [[MUL]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ] 141; GFX-NEXT: ret half [[COMMON_RET_OP]] 142; GFX: [[IF_THEN]]: 143; GFX-NEXT: [[ADD:%.*]] = fadd contract half [[Y]], [[MUL]] 144; GFX-NEXT: br label %[[COMMON_RET]] 145; GFX: [[IF_ELSE]]: 146; GFX-NEXT: [[SUB]] = fsub contract half [[MUL]], [[Y]] 147; GFX-NEXT: br label %[[COMMON_RET]] 148; 149entry: 150 %y = load half, ptr %ptr_y, align 8 151 %cmp = fcmp oeq half %y, 0.000000e+00 152 %x = load half, ptr %ptr_x, align 8 153 br i1 %cmp, label %if.then, label %if.else 154 155if.then: ; preds = %entry 156 %a_1 = load half, ptr %ptr_a, align 8 157 %mul = fmul contract half %x, %a_1 158 %add = fadd contract half %y, %mul 159 ret half %mul 160 161if.else: ; preds = %entry 162 %a_2 = load half, ptr %ptr_a, align 8 163 %mul1 = fmul contract half %x, %a_2 164 %sub = fsub contract half %mul1, %y 165 ret half %sub 166} 167 168define half @is_profitable_f16_ieee(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #1 { 169; GFX-LABEL: define half @is_profitable_f16_ieee( 170; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR1:[0-9]+]] { 171; GFX-NEXT: [[ENTRY:.*:]] 172; GFX-NEXT: [[Y:%.*]] = load half, ptr [[PTR_Y]], align 8 173; GFX-NEXT: [[CMP:%.*]] = fcmp oeq half [[Y]], 0xH0000 174; GFX-NEXT: [[X:%.*]] = load half, ptr [[PTR_X]], align 8 175; GFX-NEXT: [[A_1:%.*]] = load half, ptr [[PTR_A]], align 8 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: [[MUL]] = fmul contract half [[X]], [[A_1]] 182; GFX-NEXT: [[ADD:%.*]] = fadd contract half [[Y]], [[MUL]] 183; GFX-NEXT: br label %[[COMMON_RET]] 184; GFX: [[IF_ELSE]]: 185; GFX-NEXT: [[MUL1:%.*]] = fmul contract half [[X]], [[A_1]] 186; GFX-NEXT: [[SUB]] = fsub contract half [[MUL1]], [[Y]] 187; GFX-NEXT: br label %[[COMMON_RET]] 188; 189entry: 190 %y = load half, ptr %ptr_y, align 8 191 %cmp = fcmp oeq half %y, 0.000000e+00 192 %x = load half, ptr %ptr_x, align 8 193 br i1 %cmp, label %if.then, label %if.else 194 195if.then: ; preds = %entry 196 %a_1 = load half, ptr %ptr_a, align 8 197 %mul = fmul contract half %x, %a_1 198 %add = fadd contract half %y, %mul 199 ret half %mul 200 201if.else: ; preds = %entry 202 %a_2 = load half, ptr %ptr_a, align 8 203 %mul1 = fmul contract half %x, %a_2 204 %sub = fsub contract half %mul1, %y 205 ret half %sub 206} 207 208define bfloat @is_profitable_bfloat_preserve(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 { 209; GFX-LABEL: define bfloat @is_profitable_bfloat_preserve( 210; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] { 211; GFX-NEXT: [[ENTRY:.*:]] 212; GFX-NEXT: [[Y:%.*]] = load bfloat, ptr [[PTR_Y]], align 8 213; GFX-NEXT: [[CMP:%.*]] = fcmp oeq bfloat [[Y]], 0xR0000 214; GFX-NEXT: [[X:%.*]] = load bfloat, ptr [[PTR_X]], align 8 215; GFX-NEXT: [[A_1:%.*]] = load bfloat, ptr [[PTR_A]], align 8 216; GFX-NEXT: [[MUL:%.*]] = fmul contract bfloat [[X]], [[A_1]] 217; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] 218; GFX: [[COMMON_RET:.*]]: 219; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi bfloat [ [[MUL]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ] 220; GFX-NEXT: ret bfloat [[COMMON_RET_OP]] 221; GFX: [[IF_THEN]]: 222; GFX-NEXT: [[ADD:%.*]] = fadd contract bfloat 0xR3F80, [[MUL]] 223; GFX-NEXT: br label %[[COMMON_RET]] 224; GFX: [[IF_ELSE]]: 225; GFX-NEXT: [[SUB]] = fsub contract bfloat [[MUL]], [[Y]] 226; GFX-NEXT: br label %[[COMMON_RET]] 227; 228entry: 229 %y = load bfloat, ptr %ptr_y, align 8 230 %cmp = fcmp oeq bfloat %y, 0.000000e+00 231 %x = load bfloat, ptr %ptr_x, align 8 232 br i1 %cmp, label %if.then, label %if.else 233 234if.then: ; preds = %entry 235 %a_1 = load bfloat, ptr %ptr_a, align 8 236 %mul = fmul contract bfloat %x, %a_1 237 %add = fadd contract bfloat 1.000000e+00, %mul 238 ret bfloat %mul 239 240if.else: ; preds = %entry 241 %a_2 = load bfloat, ptr %ptr_a, align 8 242 %mul1 = fmul contract bfloat %x, %a_2 243 %sub = fsub contract bfloat %mul1, %y 244 ret bfloat %sub 245} 246 247define bfloat @is_profitable_bfloat_ieee(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #1 { 248; GFX-LABEL: define bfloat @is_profitable_bfloat_ieee( 249; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR1]] { 250; GFX-NEXT: [[ENTRY:.*:]] 251; GFX-NEXT: [[Y:%.*]] = load bfloat, ptr [[PTR_Y]], align 8 252; GFX-NEXT: [[CMP:%.*]] = fcmp oeq bfloat [[Y]], 0xR0000 253; GFX-NEXT: [[X:%.*]] = load bfloat, ptr [[PTR_X]], align 8 254; GFX-NEXT: [[A_1:%.*]] = load bfloat, ptr [[PTR_A]], align 8 255; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] 256; GFX: [[COMMON_RET:.*]]: 257; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi bfloat [ [[MUL:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ] 258; GFX-NEXT: ret bfloat [[COMMON_RET_OP]] 259; GFX: [[IF_THEN]]: 260; GFX-NEXT: [[MUL]] = fmul contract bfloat [[X]], [[A_1]] 261; GFX-NEXT: [[ADD:%.*]] = fadd contract bfloat 0xR3F80, [[MUL]] 262; GFX-NEXT: br label %[[COMMON_RET]] 263; GFX: [[IF_ELSE]]: 264; GFX-NEXT: [[MUL1:%.*]] = fmul contract bfloat [[X]], [[A_1]] 265; GFX-NEXT: [[SUB]] = fsub contract bfloat [[MUL1]], [[Y]] 266; GFX-NEXT: br label %[[COMMON_RET]] 267; 268entry: 269 %y = load bfloat, ptr %ptr_y, align 8 270 %cmp = fcmp oeq bfloat %y, 0.000000e+00 271 %x = load bfloat, ptr %ptr_x, align 8 272 br i1 %cmp, label %if.then, label %if.else 273 274if.then: ; preds = %entry 275 %a_1 = load bfloat, ptr %ptr_a, align 8 276 %mul = fmul contract bfloat %x, %a_1 277 %add = fadd contract bfloat 1.000000e+00, %mul 278 ret bfloat %mul 279 280if.else: ; preds = %entry 281 %a_2 = load bfloat, ptr %ptr_a, align 8 282 %mul1 = fmul contract bfloat %x, %a_2 283 %sub = fsub contract bfloat %mul1, %y 284 ret bfloat %sub 285} 286 287define double @is_profitable_constant(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #1 { 288; GFX-LABEL: define double @is_profitable_constant( 289; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR1]] { 290; GFX-NEXT: [[ENTRY:.*:]] 291; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8 292; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00 293; GFX-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8 294; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] 295; GFX: [[COMMON_RET:.*]]: 296; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ] 297; GFX-NEXT: ret double [[COMMON_RET_OP]] 298; GFX: [[IF_THEN]]: 299; GFX-NEXT: [[MUL:%.*]] = fmul contract double 2.000000e+00, [[X]] 300; GFX-NEXT: [[ADD]] = fadd contract double 1.000000e+00, [[MUL]] 301; GFX-NEXT: br label %[[COMMON_RET]] 302; GFX: [[IF_ELSE]]: 303; GFX-NEXT: [[MUL1:%.*]] = fmul contract double 3.000000e+00, [[X]] 304; GFX-NEXT: [[SUB]] = fsub contract double [[MUL1]], [[Y]] 305; GFX-NEXT: br label %[[COMMON_RET]] 306; 307entry: 308 %y = load double, ptr %ptr_y, align 8 309 %cmp = fcmp oeq double %y, 0.000000e+00 310 %x = load double, ptr %ptr_x, align 8 311 br i1 %cmp, label %if.then, label %if.else 312 313if.then: ; preds = %entry 314 %mul = fmul contract double 2.000000e+00, %x 315 %add = fadd contract double 1.000000e+00, %mul 316 ret double %add 317 318if.else: ; preds = %entry 319 %mul1 = fmul contract double 3.000000e+00, %x 320 %sub = fsub contract double %mul1, %y 321 ret double %sub 322} 323 324@v1_ptr = external addrspace(3) global ptr 325@v2_ptr = external addrspace(3) global ptr 326 327define <8 x half> @is_profitable_vector(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) { 328; GFX-LABEL: define <8 x half> @is_profitable_vector( 329; GFX-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR2:[0-9]+]] { 330; GFX-NEXT: [[ENTRY:.*:]] 331; GFX-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8 332; GFX-NEXT: [[X:%.*]] = load <8 x half>, ptr [[PTR_X]], align 8 333; GFX-NEXT: [[V1:%.*]] = load <8 x half>, ptr addrspace(3) @v1_ptr, align 16 334; GFX-NEXT: [[V2:%.*]] = load <8 x half>, ptr addrspace(3) @v2_ptr, align 16 335; GFX-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00 336; GFX-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] 337; GFX: [[COMMON_RET:.*]]: 338; GFX-NEXT: [[COMMON_RET_OP:%.*]] = phi <8 x half> [ [[ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ] 339; GFX-NEXT: ret <8 x half> [[COMMON_RET_OP]] 340; GFX: [[IF_THEN]]: 341; GFX-NEXT: [[MUL:%.*]] = fmul contract <8 x half> [[V1]], [[X]] 342; GFX-NEXT: [[ADD]] = fadd contract <8 x half> [[V2]], [[MUL]] 343; GFX-NEXT: br label %[[COMMON_RET]] 344; GFX: [[IF_ELSE]]: 345; GFX-NEXT: [[MUL1:%.*]] = fmul contract <8 x half> [[V1]], [[X]] 346; GFX-NEXT: [[SUB]] = fsub contract <8 x half> [[MUL1]], [[V2]] 347; GFX-NEXT: br label %[[COMMON_RET]] 348; 349entry: 350 %y = load double, ptr %ptr_y, align 8 351 %x = load <8 x half>, ptr %ptr_x, align 8 352 %v1 = load <8 x half>, ptr addrspace(3) @v1_ptr 353 %v2 = load <8 x half>, ptr addrspace(3) @v2_ptr 354 %cmp = fcmp oeq double %y, 0.000000e+00 355 br i1 %cmp, label %if.then, label %if.else 356 357if.then: ; preds = %entry 358 %mul = fmul contract <8 x half> %v1, %x 359 %add = fadd contract <8 x half> %v2, %mul 360 ret <8 x half> %add 361 362if.else: ; preds = %entry 363 %mul1 = fmul contract <8 x half> %v1, %x 364 %sub = fsub contract <8 x half> %mul1, %v2 365 ret <8 x half> %sub 366} 367 368define double @is_profitable_f64_nocontract(ptr dereferenceable(8) %ptr_x, ptr dereferenceable(8) %ptr_y, ptr dereferenceable(8) %ptr_a) #0 { 369; FP-CONTRACT-FAST-LABEL: define double @is_profitable_f64_nocontract( 370; FP-CONTRACT-FAST-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] { 371; FP-CONTRACT-FAST-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8 372; FP-CONTRACT-FAST-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00 373; FP-CONTRACT-FAST-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8 374; FP-CONTRACT-FAST-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 8 375; FP-CONTRACT-FAST-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] 376; FP-CONTRACT-FAST: [[COMMON_RET:.*]]: 377; FP-CONTRACT-FAST-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[PTR_ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ] 378; FP-CONTRACT-FAST-NEXT: ret double [[COMMON_RET_OP]] 379; FP-CONTRACT-FAST: [[IF_THEN]]: 380; FP-CONTRACT-FAST-NEXT: [[MUL:%.*]] = fmul double [[X]], [[A_1]] 381; FP-CONTRACT-FAST-NEXT: [[PTR_ADD]] = fadd double 1.000000e+00, [[MUL]] 382; FP-CONTRACT-FAST-NEXT: br label %[[COMMON_RET]] 383; FP-CONTRACT-FAST: [[IF_ELSE]]: 384; FP-CONTRACT-FAST-NEXT: [[MUL1:%.*]] = fmul double [[X]], [[A_1]] 385; FP-CONTRACT-FAST-NEXT: [[SUB]] = fsub double [[MUL1]], [[Y]] 386; FP-CONTRACT-FAST-NEXT: br label %[[COMMON_RET]] 387; 388; UNSAFE-FP-MATH-LABEL: define double @is_profitable_f64_nocontract( 389; UNSAFE-FP-MATH-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] { 390; UNSAFE-FP-MATH-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8 391; UNSAFE-FP-MATH-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00 392; UNSAFE-FP-MATH-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8 393; UNSAFE-FP-MATH-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 8 394; UNSAFE-FP-MATH-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] 395; UNSAFE-FP-MATH: [[COMMON_RET:.*]]: 396; UNSAFE-FP-MATH-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[PTR_ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ] 397; UNSAFE-FP-MATH-NEXT: ret double [[COMMON_RET_OP]] 398; UNSAFE-FP-MATH: [[IF_THEN]]: 399; UNSAFE-FP-MATH-NEXT: [[MUL:%.*]] = fmul double [[X]], [[A_1]] 400; UNSAFE-FP-MATH-NEXT: [[PTR_ADD]] = fadd double 1.000000e+00, [[MUL]] 401; UNSAFE-FP-MATH-NEXT: br label %[[COMMON_RET]] 402; UNSAFE-FP-MATH: [[IF_ELSE]]: 403; UNSAFE-FP-MATH-NEXT: [[MUL1:%.*]] = fmul double [[X]], [[A_1]] 404; UNSAFE-FP-MATH-NEXT: [[SUB]] = fsub double [[MUL1]], [[Y]] 405; UNSAFE-FP-MATH-NEXT: br label %[[COMMON_RET]] 406; 407; NO-UNSAFE-FP-MATH-LABEL: define double @is_profitable_f64_nocontract( 408; NO-UNSAFE-FP-MATH-SAME: ptr dereferenceable(8) [[PTR_X:%.*]], ptr dereferenceable(8) [[PTR_Y:%.*]], ptr dereferenceable(8) [[PTR_A:%.*]]) #[[ATTR0]] { 409; NO-UNSAFE-FP-MATH-NEXT: [[Y:%.*]] = load double, ptr [[PTR_Y]], align 8 410; NO-UNSAFE-FP-MATH-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00 411; NO-UNSAFE-FP-MATH-NEXT: [[X:%.*]] = load double, ptr [[PTR_X]], align 8 412; NO-UNSAFE-FP-MATH-NEXT: [[A_1:%.*]] = load double, ptr [[PTR_A]], align 8 413; NO-UNSAFE-FP-MATH-NEXT: [[MUL:%.*]] = fmul double [[X]], [[A_1]] 414; NO-UNSAFE-FP-MATH-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] 415; NO-UNSAFE-FP-MATH: [[COMMON_RET:.*]]: 416; NO-UNSAFE-FP-MATH-NEXT: [[COMMON_RET_OP:%.*]] = phi double [ [[PTR_ADD:%.*]], %[[IF_THEN]] ], [ [[SUB:%.*]], %[[IF_ELSE]] ] 417; NO-UNSAFE-FP-MATH-NEXT: ret double [[COMMON_RET_OP]] 418; NO-UNSAFE-FP-MATH: [[IF_THEN]]: 419; NO-UNSAFE-FP-MATH-NEXT: [[PTR_ADD]] = fadd double 1.000000e+00, [[MUL]] 420; NO-UNSAFE-FP-MATH-NEXT: br label %[[COMMON_RET]] 421; NO-UNSAFE-FP-MATH: [[IF_ELSE]]: 422; NO-UNSAFE-FP-MATH-NEXT: [[SUB]] = fsub double [[MUL]], [[Y]] 423; NO-UNSAFE-FP-MATH-NEXT: br label %[[COMMON_RET]] 424; 425 %y = load double, ptr %ptr_y, align 8 426 %cmp = fcmp oeq double %y, 0.000000e+00 427 %x = load double, ptr %ptr_x, align 8 428 br i1 %cmp, label %if.then, label %if.else 429 430if.then: ; preds = %entry 431 %a_1 = load double, ptr %ptr_a, align 8 432 %mul = fmul double %x, %a_1 433 %ptr_add = fadd double 1.000000e+00, %mul 434 ret double %ptr_add 435 436if.else: ; preds = %entry 437 %a_2 = load double, ptr %ptr_a, align 8 438 %mul1 = fmul double %x, %a_2 439 %sub = fsub double %mul1, %y 440 ret double %sub 441} 442 443attributes #0 = { nounwind "denormal-fp-math"="preserve-sign,preserve-sign" } 444attributes #1 = { nounwind "denormal-fp-math"="ieee,ieee" } 445