1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -S -passes='instcombine<no-verify-fixpoint>' < %s | FileCheck %s 3 4@x = global double 0.000000e+00 5@r1 = global double 0.000000e+00 6@r2 = global double 0.000000e+00 7@r3 = global double 0.000000e+00 8@v = global [2 x double] zeroinitializer 9@v1 = global [2 x double] zeroinitializer 10@v2 = global [2 x double] zeroinitializer 11 12; div/mul/div1 in the same block. 13define void @bb_constraint_case1(double %a) { 14; CHECK-LABEL: define void @bb_constraint_case1( 15; CHECK-SAME: double [[A:%.*]]) { 16; CHECK-NEXT: entry: 17; CHECK-NEXT: [[SQRT1:%.*]] = call reassoc double @llvm.sqrt.f64(double [[A]]) 18; CHECK-NEXT: [[TMP0:%.*]] = fdiv reassoc double 1.000000e+00, [[A]] 19; CHECK-NEXT: [[DIV:%.*]] = fmul reassoc double [[TMP0]], [[SQRT1]] 20; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 21; CHECK-NEXT: store double [[TMP0]], ptr @r1, align 8 22; CHECK-NEXT: store double [[SQRT1]], ptr @r2, align 8 23; CHECK-NEXT: ret void 24; 25entry: 26 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 27 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 28 store double %div, ptr @x 29 %mul = fmul reassoc double %div, %div 30 store double %mul, ptr @r1 31 %div1 = fdiv reassoc double %a, %sqrt 32 store double %div1, ptr @r2 33 ret void 34} 35 36; div/mul in one block and div1 in other block with conditional guard. 37define void @bb_constraint_case2(double %a, i32 %d) { 38; CHECK-LABEL: define void @bb_constraint_case2( 39; CHECK-SAME: double [[A:%.*]], i32 [[D:%.*]]) { 40; CHECK-NEXT: entry: 41; CHECK-NEXT: [[SQRT1:%.*]] = call reassoc double @llvm.sqrt.f64(double [[A]]) 42; CHECK-NEXT: [[TMP0:%.*]] = fdiv reassoc double 1.000000e+00, [[A]] 43; CHECK-NEXT: [[DIV:%.*]] = fmul reassoc double [[TMP0]], [[SQRT1]] 44; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 45; CHECK-NEXT: store double [[TMP0]], ptr @r1, align 8 46; CHECK-NEXT: [[D_NOT:%.*]] = icmp eq i32 [[D]], 0 47; CHECK-NEXT: br i1 [[D_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 48; CHECK: if.then: 49; CHECK-NEXT: store double [[SQRT1]], ptr @r2, align 8 50; CHECK-NEXT: br label [[IF_END]] 51; CHECK: if.end: 52; CHECK-NEXT: ret void 53; 54entry: 55 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 56 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 57 store double %div, ptr @x 58 %mul = fmul reassoc double %div, %div 59 store double %mul, ptr @r1 60 %d.not = icmp eq i32 %d, 0 61 br i1 %d.not, label %if.end, label %if.then 62 63if.then: ; preds = %entry 64 %div1 = fdiv reassoc double %a, %sqrt 65 store double %div1, ptr @r2 66 br label %if.end 67 68if.end: ; preds = %if.then, %entry 69 ret void 70} 71 72; div in one block. mul/div1 in other block and conditionally guarded. Don't optimize. 73define void @bb_constraint_case3(double %a, i32 %d) { 74; CHECK-LABEL: define void @bb_constraint_case3( 75; CHECK-SAME: double [[A:%.*]], i32 [[D:%.*]]) { 76; CHECK-NEXT: entry: 77; CHECK-NEXT: [[SQRT:%.*]] = call reassoc nnan ninf nsz double @llvm.sqrt.f64(double [[A]]) 78; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc ninf arcp double 1.000000e+00, [[SQRT]] 79; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 80; CHECK-NEXT: [[D_NOT:%.*]] = icmp eq i32 [[D]], 0 81; CHECK-NEXT: br i1 [[D_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 82; CHECK: if.then: 83; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[DIV]], [[DIV]] 84; CHECK-NEXT: store double [[MUL]], ptr @r1, align 8 85; CHECK-NEXT: [[DIV1:%.*]] = fdiv reassoc double [[A]], [[SQRT]] 86; CHECK-NEXT: store double [[DIV1]], ptr @r2, align 8 87; CHECK-NEXT: br label [[IF_END]] 88; CHECK: if.end: 89; CHECK-NEXT: ret void 90; 91entry: 92 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 93 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 94 store double %div, ptr @x 95 %d.not = icmp eq i32 %d, 0 96 br i1 %d.not, label %if.end, label %if.then 97 98if.then: ; preds = %entry 99 %mul = fmul reassoc double %div, %div 100 store double %mul, ptr @r1 101 %div1 = fdiv reassoc double %a, %sqrt 102 store double %div1, ptr @r2 103 br label %if.end 104 105if.end: ; preds = %if.then, %entry 106 ret void 107} 108 109; div in one block. mul/div1 each in different block and conditionally guarded. Don't optimize. 110define void @bb_constraint_case4(double %a, i32 %c, i32 %d) { 111; CHECK-LABEL: define void @bb_constraint_case4( 112; CHECK-SAME: double [[A:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) { 113; CHECK-NEXT: entry: 114; CHECK-NEXT: [[SQRT:%.*]] = call reassoc nnan ninf nsz double @llvm.sqrt.f64(double [[A]]) 115; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc ninf arcp double 1.000000e+00, [[SQRT]] 116; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 117; CHECK-NEXT: [[C_NOT:%.*]] = icmp eq i32 [[C]], 0 118; CHECK-NEXT: br i1 [[C_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 119; CHECK: if.then: 120; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[DIV]], [[DIV]] 121; CHECK-NEXT: store double [[MUL]], ptr @r1, align 8 122; CHECK-NEXT: br label [[IF_END]] 123; CHECK: if.end: 124; CHECK-NEXT: [[D_NOT:%.*]] = icmp eq i32 [[D]], 0 125; CHECK-NEXT: br i1 [[D_NOT]], label [[IF_END1:%.*]], label [[IF_THEN1:%.*]] 126; CHECK: if.then1: 127; CHECK-NEXT: [[DIV1:%.*]] = fdiv reassoc double [[A]], [[SQRT]] 128; CHECK-NEXT: store double [[DIV1]], ptr @r2, align 8 129; CHECK-NEXT: br label [[IF_END1]] 130; CHECK: if.end1: 131; CHECK-NEXT: ret void 132; 133entry: 134 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 135 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 136 store double %div, ptr @x 137 %c.not = icmp eq i32 %c, 0 138 br i1 %c.not, label %if.end, label %if.then 139 140if.then: ; preds = %entry 141 %mul = fmul reassoc double %div, %div 142 store double %mul, ptr @r1 143 br label %if.end 144 145if.end: ; preds = %if.then, %entry 146 %d.not = icmp eq i32 %d, 0 147 br i1 %d.not, label %if.end1, label %if.then1 148 149if.then1: ; preds = %if.end 150 %div1 = fdiv reassoc double %a, %sqrt 151 store double %div1, ptr @r2 152 br label %if.end1 153 154if.end1: ; preds = %if.then1, %if.end 155 ret void 156} 157 158; sqrt value comes from different blocks. Don't optimize. 159define void @bb_constraint_case5(double %a, i32 %c) { 160; CHECK-LABEL: define void @bb_constraint_case5( 161; CHECK-SAME: double [[A:%.*]], i32 [[C:%.*]]) { 162; CHECK-NEXT: entry: 163; CHECK-NEXT: [[C_NOT:%.*]] = icmp eq i32 [[C]], 0 164; CHECK-NEXT: br i1 [[C_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 165; CHECK: if.then: 166; CHECK-NEXT: [[TMP0:%.*]] = call reassoc nnan ninf nsz double @llvm.sqrt.f64(double [[A]]) 167; CHECK-NEXT: br label [[IF_END:%.*]] 168; CHECK: if.else: 169; CHECK-NEXT: [[ADD:%.*]] = fadd double [[A]], 1.000000e+01 170; CHECK-NEXT: [[TMP1:%.*]] = call reassoc nnan ninf nsz double @llvm.sqrt.f64(double [[ADD]]) 171; CHECK-NEXT: br label [[IF_END]] 172; CHECK: if.end: 173; CHECK-NEXT: [[SQRT:%.*]] = phi double [ [[TMP0]], [[IF_THEN]] ], [ [[TMP1]], [[IF_ELSE]] ] 174; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc ninf arcp double 1.000000e+00, [[SQRT]] 175; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[DIV]], [[DIV]] 176; CHECK-NEXT: store double [[MUL]], ptr @r1, align 8 177; CHECK-NEXT: [[DIV1:%.*]] = fdiv reassoc double [[A]], [[SQRT]] 178; CHECK-NEXT: store double [[DIV1]], ptr @r2, align 8 179; CHECK-NEXT: ret void 180; 181entry: 182 %c.not = icmp eq i32 %c, 0 183 br i1 %c.not, label %if.else, label %if.then 184 185if.then: ; preds = %entry 186 %0 = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 187 br label %if.end 188 189if.else: ; preds = %entry 190 %add = fadd double %a, 1.000000e+01 191 %1 = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %add) 192 br label %if.end 193 194if.end: ; preds = %if.else, %if.then 195 %sqrt = phi double[ %0, %if.then], [ %1, %if.else] 196 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 197 %mul = fmul reassoc double %div, %div 198 store double %mul, ptr @r1 199 %div1 = fdiv reassoc double %a, %sqrt 200 store double %div1, ptr @r2 201 ret void 202} 203 204; div in one block and conditionally guarded. mul/div1 in other block. Don't optimize. 205define void @bb_constraint_case6(double %a, i32 %d) { 206; CHECK-LABEL: define void @bb_constraint_case6( 207; CHECK-SAME: double [[A:%.*]], i32 [[D:%.*]]) { 208; CHECK-NEXT: entry: 209; CHECK-NEXT: [[SQRT:%.*]] = call reassoc nnan ninf nsz double @llvm.sqrt.f64(double [[A]]) 210; CHECK-NEXT: [[D_NOT:%.*]] = icmp eq i32 [[D]], 0 211; CHECK-NEXT: br i1 [[D_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 212; CHECK: if.else: 213; CHECK-NEXT: [[TMP0:%.*]] = load double, ptr @x, align 8 214; CHECK-NEXT: br label [[IF_END:%.*]] 215; CHECK: if.then: 216; CHECK-NEXT: [[TMP1:%.*]] = fdiv reassoc ninf arcp double 1.000000e+00, [[SQRT]] 217; CHECK-NEXT: store double [[TMP1]], ptr @x, align 8 218; CHECK-NEXT: br label [[IF_END]] 219; CHECK: if.end: 220; CHECK-NEXT: [[DIV:%.*]] = phi double [ [[TMP0]], [[IF_ELSE]] ], [ [[TMP1]], [[IF_THEN]] ] 221; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[DIV]], [[DIV]] 222; CHECK-NEXT: store double [[MUL]], ptr @r1, align 8 223; CHECK-NEXT: [[DIV1:%.*]] = fdiv reassoc double [[A]], [[SQRT]] 224; CHECK-NEXT: store double [[DIV1]], ptr @r2, align 8 225; CHECK-NEXT: ret void 226; 227entry: 228 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 229 %d.not = icmp eq i32 %d, 0 230 br i1 %d.not, label %if.else, label %if.then 231 232if.else: ; preds = %entry 233 %1 = load double, ptr @x 234 br label %if.end 235 236if.then: ; preds = %entry 237 %2 = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 238 store double %2, ptr @x 239 br label %if.end 240 241if.end: ; preds = %if.else, %if.then 242 %div = phi double [ %1, %if.else ], [ %2, %if.then ] 243 %mul = fmul reassoc double %div, %div 244 store double %mul, ptr @r1 245 %div1 = fdiv reassoc double %a, %sqrt 246 store double %div1, ptr @r2 247 ret void 248} 249 250; value for mul comes from different blocks. Don't optimize. 251define void @bb_constraint_case7(double %a, i32 %c, i32 %d) { 252; CHECK-LABEL: define void @bb_constraint_case7( 253; CHECK-SAME: double [[A:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) { 254; CHECK-NEXT: entry: 255; CHECK-NEXT: [[SQRT:%.*]] = call reassoc nnan ninf nsz double @llvm.sqrt.f64(double [[A]]) 256; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc ninf arcp double 1.000000e+00, [[SQRT]] 257; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 258; CHECK-NEXT: [[C_NOT:%.*]] = icmp eq i32 [[C]], 0 259; CHECK-NEXT: br i1 [[C_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 260; CHECK: if.then: 261; CHECK-NEXT: [[TMP0:%.*]] = fdiv double 3.000000e+00, [[A]] 262; CHECK-NEXT: br label [[IF_END:%.*]] 263; CHECK: if.else: 264; CHECK-NEXT: [[D_NOT:%.*]] = icmp eq i32 [[D]], 0 265; CHECK-NEXT: br i1 [[D_NOT]], label [[IF_ELSE1:%.*]], label [[IF_THEN1:%.*]] 266; CHECK: if.then1: 267; CHECK-NEXT: [[TMP1:%.*]] = fdiv double 2.000000e+00, [[A]] 268; CHECK-NEXT: br label [[IF_END]] 269; CHECK: if.else1: 270; CHECK-NEXT: [[TMP2:%.*]] = fmul reassoc double [[DIV]], [[DIV]] 271; CHECK-NEXT: br label [[IF_END]] 272; CHECK: if.end: 273; CHECK-NEXT: [[MUL:%.*]] = phi double [ [[TMP1]], [[IF_THEN1]] ], [ [[TMP2]], [[IF_ELSE1]] ], [ [[TMP0]], [[IF_THEN]] ] 274; CHECK-NEXT: store double [[MUL]], ptr @r1, align 8 275; CHECK-NEXT: [[DIV1:%.*]] = fdiv reassoc double [[A]], [[SQRT]] 276; CHECK-NEXT: store double [[DIV1]], ptr @r2, align 8 277; CHECK-NEXT: ret void 278; 279entry: 280 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 281 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 282 store double %div, ptr @x 283 %c.not = icmp eq i32 %c, 0 284 br i1 %c.not, label %if.else, label %if.then 285 286if.then: ; preds = %entry 287 %1 = fdiv double 3.000000e+00, %a 288 br label %if.end 289 290if.else: ; preds = %entry 291 %d.not = icmp eq i32 %d, 0 292 br i1 %d.not, label %if.else1, label %if.then1 293 294if.then1: ; preds = %if.else 295 %2 = fdiv double 2.000000e+00, %a 296 br label %if.end 297 298if.else1: ; preds = %if.else 299 %3 = fmul reassoc double %div, %div 300 br label %if.end 301 302if.end: ; preds = %if.then1, %if.else1, %if.then 303 %mul = phi double [ %2, %if.then1 ], [ %3, %if.else1 ], [ %1, %if.then ] 304 store double %mul, ptr @r1 305 %div1 = fdiv reassoc double %a, %sqrt 306 store double %div1, ptr @r2 307 ret void 308} 309 310; value of mul comes from two different blocks(as shown by select ins). 311define void @bb_constraint_case8(double %a, i32 %c) { 312; CHECK-LABEL: define void @bb_constraint_case8( 313; CHECK-SAME: double [[A:%.*]], i32 [[C:%.*]]) { 314; CHECK-NEXT: entry: 315; CHECK-NEXT: [[SQRT1:%.*]] = call reassoc double @llvm.sqrt.f64(double [[A]]) 316; CHECK-NEXT: [[TMP0:%.*]] = fdiv reassoc double 1.000000e+00, [[A]] 317; CHECK-NEXT: [[DIV:%.*]] = fmul reassoc double [[TMP0]], [[SQRT1]] 318; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 319; CHECK-NEXT: [[C_NOT:%.*]] = icmp eq i32 [[C]], 0 320; CHECK-NEXT: [[TMP1:%.*]] = fmul double [[A]], [[A]] 321; CHECK-NEXT: [[MUL:%.*]] = select i1 [[C_NOT]], double [[TMP1]], double [[TMP0]] 322; CHECK-NEXT: store double [[MUL]], ptr @r1, align 8 323; CHECK-NEXT: store double [[SQRT1]], ptr @r2, align 8 324; CHECK-NEXT: ret void 325; 326entry: 327 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 328 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 329 store double %div, ptr @x 330 %c.not = icmp eq i32 %c, 0 331 %1 = fmul double %a, %a 332 %2 = fmul reassoc double %div, %div 333 %mul = select i1 %c.not, double %1, double %2 334 store double %mul, ptr @r1 335 %div1 = fdiv reassoc double %a, %sqrt 336 store double %div1, ptr @r2 337 ret void 338} 339 340; multiple instances of multiply ops to optimize. Optimize all. 341define void @mutiple_multiply_instances(double %a, i32 %c) { 342; CHECK-LABEL: define void @mutiple_multiply_instances( 343; CHECK-SAME: double [[A:%.*]], i32 [[C:%.*]]) { 344; CHECK-NEXT: entry: 345; CHECK-NEXT: [[SQRT1:%.*]] = call reassoc double @llvm.sqrt.f64(double [[A]]) 346; CHECK-NEXT: [[TMP1:%.*]] = fdiv reassoc double 1.000000e+00, [[A]] 347; CHECK-NEXT: [[DIV:%.*]] = fmul reassoc double [[TMP1]], [[SQRT1]] 348; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 349; CHECK-NEXT: [[C_NOT:%.*]] = icmp eq i32 [[C]], 0 350; CHECK-NEXT: [[TMP2:%.*]] = fmul double [[A]], [[A]] 351; CHECK-NEXT: [[TMP3:%.*]] = fmul double [[A]], [[A]] 352; CHECK-NEXT: [[MUL1:%.*]] = select i1 [[C_NOT]], double [[TMP2]], double [[TMP1]] 353; CHECK-NEXT: [[MUL2:%.*]] = select i1 [[C_NOT]], double [[TMP1]], double [[TMP3]] 354; CHECK-NEXT: store double [[MUL1]], ptr @r1, align 8 355; CHECK-NEXT: store double [[MUL2]], ptr @r3, align 8 356; CHECK-NEXT: store double [[SQRT1]], ptr @r2, align 8 357; CHECK-NEXT: ret void 358; 359entry: 360 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 361 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 362 store double %div, ptr @x 363 %c.not = icmp eq i32 %c, 0 364 %1 = fmul double %a, %a 365 %2 = fmul double %a, %a 366 %3 = fmul reassoc double %div, %div 367 %4 = fmul reassoc double %div, %div 368 %mul1 = select i1 %c.not, double %1, double %3 369 %mul2 = select i1 %c.not, double %4, double %2 370 store double %mul1, ptr @r1 371 store double %mul2, ptr @r3 372 %div1 = fdiv reassoc double %a, %sqrt 373 store double %div1, ptr @r2 374 ret void 375} 376 377; missing flags for optimization. 378define void @missing_arcp_flag_on_div(double %a) { 379; CHECK-LABEL: define void @missing_arcp_flag_on_div( 380; CHECK-SAME: double [[A:%.*]]) { 381; CHECK-NEXT: entry: 382; CHECK-NEXT: [[SQRT:%.*]] = call reassoc nnan ninf nsz double @llvm.sqrt.f64(double [[A]]) 383; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc ninf double 1.000000e+00, [[SQRT]] 384; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 385; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[DIV]], [[DIV]] 386; CHECK-NEXT: store double [[MUL]], ptr @r1, align 8 387; CHECK-NEXT: [[DIV1:%.*]] = fdiv reassoc double [[A]], [[SQRT]] 388; CHECK-NEXT: store double [[DIV1]], ptr @r2, align 8 389; CHECK-NEXT: ret void 390; 391entry: 392 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 393 %div = fdiv reassoc ninf double 1.000000e+00, %sqrt 394 store double %div, ptr @x 395 %mul = fmul reassoc double %div, %div 396 store double %mul, ptr @r1 397 %div1 = fdiv reassoc double %a, %sqrt 398 store double %div1, ptr @r2 399 ret void 400} 401 402; missing flags for optimization. 403define void @missing_reassoc_flag_on_mul(double %a) { 404; CHECK-LABEL: define void @missing_reassoc_flag_on_mul( 405; CHECK-SAME: double [[A:%.*]]) { 406; CHECK-NEXT: entry: 407; CHECK-NEXT: [[SQRT:%.*]] = call reassoc nnan ninf nsz double @llvm.sqrt.f64(double [[A]]) 408; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc ninf arcp double 1.000000e+00, [[SQRT]] 409; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 410; CHECK-NEXT: [[MUL:%.*]] = fmul double [[DIV]], [[DIV]] 411; CHECK-NEXT: store double [[MUL]], ptr @r1, align 8 412; CHECK-NEXT: [[DIV1:%.*]] = fdiv reassoc double [[A]], [[SQRT]] 413; CHECK-NEXT: store double [[DIV1]], ptr @r2, align 8 414; CHECK-NEXT: ret void 415; 416entry: 417 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 418 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 419 store double %div, ptr @x 420 %mul = fmul double %div, %div 421 store double %mul, ptr @r1 422 %div1 = fdiv reassoc double %a, %sqrt 423 store double %div1, ptr @r2 424 ret void 425} 426 427; missing flags for optimization. 428define void @missing_reassoc_flag_on_div1(double %a) { 429; CHECK-LABEL: define void @missing_reassoc_flag_on_div1( 430; CHECK-SAME: double [[A:%.*]]) { 431; CHECK-NEXT: entry: 432; CHECK-NEXT: [[SQRT:%.*]] = call reassoc nnan ninf nsz double @llvm.sqrt.f64(double [[A]]) 433; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc ninf arcp double 1.000000e+00, [[SQRT]] 434; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 435; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[DIV]], [[DIV]] 436; CHECK-NEXT: store double [[MUL]], ptr @r1, align 8 437; CHECK-NEXT: [[DIV1:%.*]] = fdiv double [[A]], [[SQRT]] 438; CHECK-NEXT: store double [[DIV1]], ptr @r2, align 8 439; CHECK-NEXT: ret void 440; 441entry: 442 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 443 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 444 store double %div, ptr @x 445 %mul = fmul reassoc double %div, %div 446 store double %mul, ptr @r1 447 %div1 = fdiv double %a, %sqrt 448 store double %div1, ptr @r2 449 ret void 450} 451 452; div = -1/sqrt(a) 453define void @negative_fdiv_val(double %a) { 454; CHECK-LABEL: define void @negative_fdiv_val( 455; CHECK-SAME: double [[A:%.*]]) { 456; CHECK-NEXT: entry: 457; CHECK-NEXT: [[SQRT1:%.*]] = call reassoc double @llvm.sqrt.f64(double [[A]]) 458; CHECK-NEXT: [[TMP0:%.*]] = fdiv reassoc double 1.000000e+00, [[A]] 459; CHECK-NEXT: [[TMP1:%.*]] = fneg reassoc double [[SQRT1]] 460; CHECK-NEXT: [[DIV:%.*]] = fmul reassoc double [[TMP0]], [[TMP1]] 461; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 462; CHECK-NEXT: store double [[TMP0]], ptr @r1, align 8 463; CHECK-NEXT: store double [[SQRT1]], ptr @r2, align 8 464; CHECK-NEXT: ret void 465; 466entry: 467 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 468 %div = fdiv reassoc arcp ninf double -1.000000e+00, %sqrt 469 store double %div, ptr @x 470 %mul = fmul reassoc double %div, %div 471 store double %mul, ptr @r1 472 %div1 = fdiv reassoc double %a, %sqrt 473 store double %div1, ptr @r2 474 ret void 475} 476 477define void @fpmath_metadata_on_div1(double %a) { 478; CHECK-LABEL: define void @fpmath_metadata_on_div1( 479; CHECK-SAME: double [[A:%.*]]) { 480; CHECK-NEXT: entry: 481; CHECK-NEXT: [[SQRT1:%.*]] = call reassoc double @llvm.sqrt.f64(double [[A]]), !fpmath [[META0:![0-9]+]] 482; CHECK-NEXT: [[TMP0:%.*]] = fdiv reassoc double 1.000000e+00, [[A]] 483; CHECK-NEXT: [[DIV:%.*]] = fmul reassoc double [[TMP0]], [[SQRT1]] 484; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 485; CHECK-NEXT: store double [[TMP0]], ptr @r1, align 8 486; CHECK-NEXT: store double [[SQRT1]], ptr @r2, align 8 487; CHECK-NEXT: ret void 488; 489entry: 490 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 491 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 492 store double %div, ptr @x 493 %mul = fmul reassoc double %div, %div 494 store double %mul, ptr @r1 495 %div1 = fdiv reassoc double %a, %sqrt, !fpmath !3 496 store double %div1, ptr @r2 497 ret void 498} 499 500define void @fpmath_metadata_on_mul(double %a) { 501; CHECK-LABEL: define void @fpmath_metadata_on_mul( 502; CHECK-SAME: double [[A:%.*]]) { 503; CHECK-NEXT: entry: 504; CHECK-NEXT: [[SQRT1:%.*]] = call reassoc double @llvm.sqrt.f64(double [[A]]) 505; CHECK-NEXT: [[TMP0:%.*]] = fdiv reassoc double 1.000000e+00, [[A]], !fpmath [[META1:![0-9]+]] 506; CHECK-NEXT: [[DIV:%.*]] = fmul reassoc double [[TMP0]], [[SQRT1]] 507; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 508; CHECK-NEXT: store double [[TMP0]], ptr @r1, align 8 509; CHECK-NEXT: store double [[SQRT1]], ptr @r2, align 8 510; CHECK-NEXT: ret void 511; 512entry: 513 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 514 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt 515 store double %div, ptr @x 516 %mul = fmul reassoc double %div, %div, !fpmath !2 517 store double %mul, ptr @r1 518 %div1 = fdiv reassoc double %a, %sqrt 519 store double %div1, ptr @r2 520 ret void 521} 522 523; FIXME: DIV in the result should get the fpmath metadata from %div. 524define void @fpmath_metadata_on_div(double %a) { 525; CHECK-LABEL: define void @fpmath_metadata_on_div( 526; CHECK-SAME: double [[A:%.*]]) { 527; CHECK-NEXT: entry: 528; CHECK-NEXT: [[SQRT1:%.*]] = call reassoc double @llvm.sqrt.f64(double [[A]]) 529; CHECK-NEXT: [[TMP0:%.*]] = fdiv reassoc double 1.000000e+00, [[A]] 530; CHECK-NEXT: [[DIV:%.*]] = fmul reassoc double [[TMP0]], [[SQRT1]], !fpmath [[META2:![0-9]+]] 531; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 532; CHECK-NEXT: store double [[TMP0]], ptr @r1, align 8 533; CHECK-NEXT: store double [[SQRT1]], ptr @r2, align 8 534; CHECK-NEXT: ret void 535; 536entry: 537 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a) 538 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt, !fpmath !1 539 store double %div, ptr @x 540 %mul = fmul reassoc double %div, %div 541 store double %mul, ptr @r1 542 %div1 = fdiv reassoc double %a, %sqrt 543 store double %div1, ptr @r2 544 ret void 545} 546 547define void @fpmath_metadata_on_all(double %a) { 548; CHECK-LABEL: define void @fpmath_metadata_on_all( 549; CHECK-SAME: double [[A:%.*]]) { 550; CHECK-NEXT: entry: 551; CHECK-NEXT: [[SQRT1:%.*]] = call reassoc double @llvm.sqrt.f64(double [[A]]), !fpmath [[META0]] 552; CHECK-NEXT: [[TMP0:%.*]] = fdiv reassoc double 1.000000e+00, [[A]], !fpmath [[META1]] 553; CHECK-NEXT: [[DIV:%.*]] = fmul reassoc double [[TMP0]], [[SQRT1]], !fpmath [[META2]] 554; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 555; CHECK-NEXT: store double [[TMP0]], ptr @r1, align 8 556; CHECK-NEXT: store double [[SQRT1]], ptr @r2, align 8 557; CHECK-NEXT: ret void 558; 559entry: 560 %sqrt = call reassoc nnan nsz ninf double @llvm.sqrt.f64(double %a), !fpmath !0 561 %div = fdiv reassoc arcp ninf double 1.000000e+00, %sqrt, !fpmath !1 562 store double %div, ptr @x 563 %mul = fmul reassoc double %div, %div, !fpmath !2 564 store double %mul, ptr @r1 565 %div1 = fdiv reassoc double %a, %sqrt, !fpmath !3 566 store double %div1, ptr @r2 567 ret void 568} 569 570define void @vector_input(<2 x double> %a) { 571; CHECK-LABEL: define void @vector_input( 572; CHECK-SAME: <2 x double> [[A:%.*]]) { 573; CHECK-NEXT: entry: 574; CHECK-NEXT: [[SQRT1:%.*]] = call reassoc <2 x double> @llvm.sqrt.v2f64(<2 x double> [[A]]) 575; CHECK-NEXT: [[TMP0:%.*]] = fdiv reassoc <2 x double> splat (double 1.000000e+00), [[A]] 576; CHECK-NEXT: [[DIV:%.*]] = fmul reassoc <2 x double> [[TMP0]], [[SQRT1]] 577; CHECK-NEXT: store <2 x double> [[DIV]], ptr @v, align 16 578; CHECK-NEXT: store <2 x double> [[TMP0]], ptr @v1, align 16 579; CHECK-NEXT: store <2 x double> [[SQRT1]], ptr @v2, align 16 580; CHECK-NEXT: ret void 581; 582entry: 583 %sqrt = call reassoc nnan nsz ninf <2 x double> @llvm.sqrt.v2f64(<2 x double> %a) 584 %div = fdiv reassoc arcp ninf <2 x double><double 1.000000e+00, double 1.000000e+00>, %sqrt 585 store <2 x double> %div, ptr @v 586 %mul = fmul reassoc <2 x double> %div, %div 587 store <2 x double> %mul, ptr @v1 588 %div1 = fdiv reassoc <2 x double> %a, %sqrt 589 store <2 x double> %div1, ptr @v2 590 ret void 591} 592 593define void @strict_fp_metadata(double %a) { 594; CHECK-LABEL: define void @strict_fp_metadata( 595; CHECK-SAME: double [[A:%.*]]) { 596; CHECK-NEXT: entry: 597; CHECK-NEXT: [[CONV:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 1, metadata !"round.dynamic", metadata !"fpexcept.strict") 598; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.sqrt.f64(double noundef [[A]]) 599; CHECK-NEXT: [[DIV:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[CONV]], double [[CALL]], metadata !"round.dynamic", metadata !"fpexcept.strict") 600; CHECK-NEXT: store double [[DIV]], ptr @x, align 8 601; CHECK-NEXT: [[MUL:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[DIV]], double [[DIV]], metadata !"round.dynamic", metadata !"fpexcept.strict") 602; CHECK-NEXT: store double [[MUL]], ptr @r1, align 8 603; CHECK-NEXT: [[DIV2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A]], double [[CALL]], metadata !"round.dynamic", metadata !"fpexcept.strict") 604; CHECK-NEXT: store double [[DIV2]], ptr @r2, align 8 605; CHECK-NEXT: ret void 606; 607entry: 608 %conv = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 1, metadata !"round.dynamic", metadata !"fpexcept.strict") 609 %call = call double @llvm.sqrt.f64(double noundef %a) 610 %div = call double @llvm.experimental.constrained.fdiv.f64(double %conv, double %call, metadata !"round.dynamic", metadata !"fpexcept.strict") 611 store double %div, ptr @x 612 %mul = call double @llvm.experimental.constrained.fmul.f64(double %div, double %div, metadata !"round.dynamic", metadata !"fpexcept.strict") 613 store double %mul, ptr @r1 614 %div2 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %call, metadata !"round.dynamic", metadata !"fpexcept.strict") 615 store double %div2, ptr @r2 616 ret void 617} 618 619declare double @llvm.experimental.constrained.sitofp.f64.i32(i32, metadata, metadata) 620declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata) 621declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata) 622declare double @llvm.sqrt.f64(double) 623declare <2 x double> @llvm.sqrt.v2f64(<2 x double>) 624 625!0 = !{float 2.5} 626!1 = !{float 3.5} 627!2 = !{float 4.5} 628!3 = !{float 5.5} 629; CHECK: [[META0]] = !{float 5.500000e+00} 630; CHECK: [[META1]] = !{float 4.500000e+00} 631; CHECK: [[META2]] = !{float 3.500000e+00} 632