1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals --version 2 2; RUN: opt -S -passes=attributor < %s | FileCheck %s 3 4; Keep the attribute checks clean by disabling inference of anything else. 5declare void @call_of_mystery() 6 7; Should infer to ieee,ieee/default 8define internal void @leaf_dynamic_dynamic_from_ieee_ieee() #0 { 9; CHECK-LABEL: define internal void @leaf_dynamic_dynamic_from_ieee_ieee() { 10; CHECK-NEXT: call void @call_of_mystery() 11; CHECK-NEXT: ret void 12; 13 call void @call_of_mystery() 14 ret void 15} 16 17; Should infer to ieee,ieee/default 18define internal void @leaf_recursive_dynamic_dynamic_from_ieee_ieee() #0 { 19; CHECK-LABEL: define internal void @leaf_recursive_dynamic_dynamic_from_ieee_ieee() { 20; CHECK-NEXT: call void @call_of_mystery() 21; CHECK-NEXT: call void @leaf_recursive_dynamic_dynamic_from_ieee_ieee() 22; CHECK-NEXT: ret void 23; 24 call void @call_of_mystery() 25 call void @leaf_recursive_dynamic_dynamic_from_ieee_ieee() 26 ret void 27} 28 29; Should strip denormal-fp-math for default ieee 30define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_ieee_ieee() #1 { 31; CHECK-LABEL: define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_ieee_ieee() { 32; CHECK-NEXT: call void @call_of_mystery() 33; CHECK-NEXT: ret void 34; 35 call void @call_of_mystery() 36 ret void 37} 38 39; Should infer to preserve-sign,preserve-sign 40define internal void @leaf_dynamic_dynamic_from_daz_daz() #0 { 41; CHECK-LABEL: define internal void @leaf_dynamic_dynamic_from_daz_daz 42; CHECK-SAME: () #[[ATTR0:[0-9]+]] { 43; CHECK-NEXT: call void @call_of_mystery() 44; CHECK-NEXT: ret void 45; 46 call void @call_of_mystery() 47 ret void 48} 49 50; This goes to invalid because of the mismatch in the main mode. We 51; could theoretically refine to denormal-fp-math-f32=preserve-sign,preserve-sign 52define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz() #1 { 53; CHECK-LABEL: define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz 54; CHECK-SAME: () #[[ATTR1:[0-9]+]] { 55; CHECK-NEXT: call void @call_of_mystery() 56; CHECK-NEXT: ret void 57; 58 call void @call_of_mystery() 59 ret void 60} 61 62; Leave this alone, must stay dynamic,dynamic 63define internal void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee() #0 { 64; CHECK-LABEL: define internal void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee 65; CHECK-SAME: () #[[ATTR2:[0-9]+]] { 66; CHECK-NEXT: call void @call_of_mystery() 67; CHECK-NEXT: ret void 68; 69 call void @call_of_mystery() 70 ret void 71} 72 73; Leave this alone, should only have denormal-fp-math-f32=ieee,ieee 74define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz_and_ieee_ieee() #1 { 75; CHECK-LABEL: define internal void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz_and_ieee_ieee 76; CHECK-SAME: () #[[ATTR1]] { 77; CHECK-NEXT: call void @call_of_mystery() 78; CHECK-NEXT: ret void 79; 80 call void @call_of_mystery() 81 ret void 82} 83 84; Leave as dynamic,dynamic 85define void @externally_visible_dynamic_dynamic_from_ieee_ieee() #0 { 86; CHECK-LABEL: define void @externally_visible_dynamic_dynamic_from_ieee_ieee 87; CHECK-SAME: () #[[ATTR2]] { 88; CHECK-NEXT: call void @call_of_mystery() 89; CHECK-NEXT: ret void 90; 91 call void @call_of_mystery() 92 ret void 93} 94 95; Should infer to positive-zero,positive-zero 96define internal void @leaf_dynamic_dynamic_from_dapz_dapz() #0 { 97; CHECK-LABEL: define internal void @leaf_dynamic_dynamic_from_dapz_dapz 98; CHECK-SAME: () #[[ATTR3:[0-9]+]] { 99; CHECK-NEXT: call void @call_of_mystery() 100; CHECK-NEXT: ret void 101; 102 call void @call_of_mystery() 103 ret void 104} 105 106; ieee,ieee entry point 107define void @func_ieee_ieee() #2 { 108; CHECK-LABEL: define void @func_ieee_ieee() { 109; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_ieee_ieee() 110; CHECK-NEXT: call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_ieee_ieee() 111; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee() 112; CHECK-NEXT: call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz_and_ieee_ieee() 113; CHECK-NEXT: call void @externally_visible_dynamic_dynamic_from_ieee_ieee() 114; CHECK-NEXT: call void @leaf_dynamic_ieee_from_ieee_ieee() 115; CHECK-NEXT: call void @leaf_ieee_dynamic_from_ieee_ieee() 116; CHECK-NEXT: call void @leaf_recursive_dynamic_dynamic_from_ieee_ieee() 117; CHECK-NEXT: ret void 118; 119 call void @leaf_dynamic_dynamic_from_ieee_ieee() 120 call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_ieee_ieee() 121 call void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee() 122 call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz_and_ieee_ieee() 123 call void @externally_visible_dynamic_dynamic_from_ieee_ieee() 124 call void @leaf_dynamic_ieee_from_ieee_ieee() 125 call void @leaf_ieee_dynamic_from_ieee_ieee() 126 call void @leaf_recursive_dynamic_dynamic_from_ieee_ieee() 127 ret void 128} 129 130; ieee,ieee entry point 131define void @func_default_is_ieee_ieee() { 132; CHECK-LABEL: define void @func_default_is_ieee_ieee() { 133; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_ieee_ieee() 134; CHECK-NEXT: call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_ieee_ieee() 135; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee() 136; CHECK-NEXT: call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz_and_ieee_ieee() 137; CHECK-NEXT: call void @externally_visible_dynamic_dynamic_from_ieee_ieee() 138; CHECK-NEXT: call void @leaf_dynamic_ieee_from_ieee_ieee() 139; CHECK-NEXT: call void @leaf_ieee_dynamic_from_ieee_ieee() 140; CHECK-NEXT: call void @leaf_recursive_dynamic_dynamic_from_ieee_ieee() 141; CHECK-NEXT: ret void 142; 143 call void @leaf_dynamic_dynamic_from_ieee_ieee() 144 call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_ieee_ieee() 145 call void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee() 146 call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz_and_ieee_ieee() 147 call void @externally_visible_dynamic_dynamic_from_ieee_ieee() 148 call void @leaf_dynamic_ieee_from_ieee_ieee() 149 call void @leaf_ieee_dynamic_from_ieee_ieee() 150 call void @leaf_recursive_dynamic_dynamic_from_ieee_ieee() 151 ret void 152} 153 154; preserve-sign,preserve-sign entry point 155define void @func_daz_daz() #3 { 156; CHECK-LABEL: define void @func_daz_daz 157; CHECK-SAME: () #[[ATTR0]] { 158; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_daz_daz() 159; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee() 160; CHECK-NEXT: call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz_and_ieee_ieee() 161; CHECK-NEXT: call void @leaf_f64_dynamic_f64_dynamic__f32_daz_f32_daz_from__daz_daz() 162; CHECK-NEXT: call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz() 163; CHECK-NEXT: ret void 164; 165 call void @leaf_dynamic_dynamic_from_daz_daz() 166 call void @leaf_dynamic_dynamic_from_daz_daz_and_ieee_ieee() 167 call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz_and_ieee_ieee() 168 call void @leaf_f64_dynamic_f64_dynamic__f32_daz_f32_daz_from__daz_daz() 169 call void @leaf_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic__dynamic_dynamic_from_daz_daz() 170 ret void 171} 172 173; positive-zero,positive-zero entry point 174define void @func_dapz_dapz() #4 { 175; CHECK-LABEL: define void @func_dapz_dapz 176; CHECK-SAME: () #[[ATTR3]] { 177; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_dapz_dapz() 178; CHECK-NEXT: ret void 179; 180 call void @leaf_dynamic_dynamic_from_dapz_dapz() 181 ret void 182} 183 184; Could be fully preserve-sign,preserve-sign, but this isn't a 185; realistic case and we don't bother trying to handle it. 186define internal void @leaf_f64_dynamic_f64_dynamic__f32_daz_f32_daz_from__daz_daz() #5 { 187; CHECK-LABEL: define internal void @leaf_f64_dynamic_f64_dynamic__f32_daz_f32_daz_from__daz_daz 188; CHECK-SAME: () #[[ATTR4:[0-9]+]] { 189; CHECK-NEXT: call void @call_of_mystery() 190; CHECK-NEXT: ret void 191; 192 call void @call_of_mystery() 193 ret void 194} 195 196; -> ieee,ieee 197define internal void @leaf_dynamic_ieee_from_ieee_ieee() #6 { 198; CHECK-LABEL: define internal void @leaf_dynamic_ieee_from_ieee_ieee() { 199; CHECK-NEXT: call void @call_of_mystery() 200; CHECK-NEXT: ret void 201; 202 call void @call_of_mystery() 203 ret void 204} 205 206; -> ieee,ieee 207define internal void @leaf_ieee_dynamic_from_ieee_ieee() #7 { 208; CHECK-LABEL: define internal void @leaf_ieee_dynamic_from_ieee_ieee() { 209; CHECK-NEXT: call void @call_of_mystery() 210; CHECK-NEXT: ret void 211; 212 call void @call_of_mystery() 213 ret void 214} 215 216; Specialize the f64 mode to ieee,ieee but leave f32 as dynamic,dynamic 217define internal void @leaf_dynamic_dynamic_from_f64_ieee_f32_dynamic() #0 { 218; CHECK-LABEL: define internal void @leaf_dynamic_dynamic_from_f64_ieee_f32_dynamic 219; CHECK-SAME: () #[[ATTR1]] { 220; CHECK-NEXT: call void @call_of_mystery() 221; CHECK-NEXT: ret void 222; 223 call void @call_of_mystery() 224 ret void 225} 226 227define void @func_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic() #1 { 228; CHECK-LABEL: define void @func_f64_ieee_f64_ieee__f32_dynamic_f32_dynamic 229; CHECK-SAME: () #[[ATTR1]] { 230; CHECK-NEXT: call void @leaf_dynamic_dynamic_from_f64_ieee_f32_dynamic() 231; CHECK-NEXT: ret void 232; 233 call void @leaf_dynamic_dynamic_from_f64_ieee_f32_dynamic() 234 ret void 235} 236 237; -> preserve-sign,ieee. 238define internal void @leaf_daz_dynamic_from_dynamic_ieee() #8 { 239; CHECK-LABEL: define internal void @leaf_daz_dynamic_from_dynamic_ieee 240; CHECK-SAME: () #[[ATTR5:[0-9]+]] { 241; CHECK-NEXT: call void @call_of_mystery() 242; CHECK-NEXT: ret void 243; 244 call void @call_of_mystery() 245 ret void 246} 247 248define void @dynamic_ieee() #6 { 249; CHECK-LABEL: define void @dynamic_ieee 250; CHECK-SAME: () #[[ATTR6:[0-9]+]] { 251; CHECK-NEXT: call void @leaf_daz_dynamic_from_dynamic_ieee() 252; CHECK-NEXT: ret void 253; 254 call void @leaf_daz_dynamic_from_dynamic_ieee() 255 ret void 256} 257 258; Leave unchanged as ieee,ieeee 259define internal void @leaf_ieee_ieee_from_dynamic() { 260; CHECK-LABEL: define internal void @leaf_ieee_ieee_from_dynamic() { 261; CHECK-NEXT: call void @call_of_mystery() 262; CHECK-NEXT: ret void 263; 264 call void @call_of_mystery() 265 ret void 266} 267 268; Leave unchanged as dynamic,dynamic 269define internal void @leaf_dynamic_from_dynamic() { 270; CHECK-LABEL: define internal void @leaf_dynamic_from_dynamic() { 271; CHECK-NEXT: call void @call_of_mystery() 272; CHECK-NEXT: ret void 273; 274 call void @call_of_mystery() 275 ret void 276} 277 278; Leave unchanged as preserve-sign,preserve-sign 279define internal void @leaf_daz_daz_from_dynamic() #3 { 280; CHECK-LABEL: define internal void @leaf_daz_daz_from_dynamic 281; CHECK-SAME: () #[[ATTR0]] { 282; CHECK-NEXT: call void @call_of_mystery() 283; CHECK-NEXT: ret void 284; 285 call void @call_of_mystery() 286 ret void 287} 288 289define void @dynamic_dynamic() #0 { 290; CHECK-LABEL: define void @dynamic_dynamic 291; CHECK-SAME: () #[[ATTR2]] { 292; CHECK-NEXT: call void @leaf_ieee_ieee_from_dynamic() 293; CHECK-NEXT: call void @leaf_daz_daz_from_dynamic() 294; CHECK-NEXT: call void @leaf_dynamic_from_dynamic() 295; CHECK-NEXT: ret void 296; 297 call void @leaf_ieee_ieee_from_dynamic() 298 call void @leaf_daz_daz_from_dynamic() 299 call void @leaf_dynamic_from_dynamic() 300 ret void 301} 302 303define internal void @leaf_ieee_f64_daz_f32() #9 { 304; CHECK-LABEL: define internal void @leaf_ieee_f64_daz_f32 305; CHECK-SAME: () #[[ATTR7:[0-9]+]] { 306; CHECK-NEXT: call void @call_of_mystery() 307; CHECK-NEXT: ret void 308; 309 call void @call_of_mystery() 310 ret void 311} 312 313define internal void @leaf_ieee_f64_daz_f32_from_ieee_f64_dynamic_f32() #10 { 314; CHECK-LABEL: define internal void @leaf_ieee_f64_daz_f32_from_ieee_f64_dynamic_f32 315; CHECK-SAME: () #[[ATTR8:[0-9]+]] { 316; CHECK-NEXT: call void @call_of_mystery() 317; CHECK-NEXT: ret void 318; 319 call void @call_of_mystery() 320 ret void 321} 322 323define void @ieee_f64_dynamic_f32() #1 { 324; CHECK-LABEL: define void @ieee_f64_dynamic_f32 325; CHECK-SAME: () #[[ATTR1]] { 326; CHECK-NEXT: call void @leaf_ieee_f64_daz_f32() 327; CHECK-NEXT: call void @leaf_ieee_f64_daz_f32_from_ieee_f64_dynamic_f32() 328; CHECK-NEXT: ret void 329; 330 call void @leaf_ieee_f64_daz_f32() 331 call void @leaf_ieee_f64_daz_f32_from_ieee_f64_dynamic_f32() 332 ret void 333} 334 335; => "preserve-sign,positive-zero" + "denormal-fp-math-f32"="ieee,positive-zero" 336define internal void @leaf_daz_dynamic_dynamic_dapz_from_daz_dapz_ieee_dapz() #11 { 337; CHECK-LABEL: define internal void @leaf_daz_dynamic_dynamic_dapz_from_daz_dapz_ieee_dapz 338; CHECK-SAME: () #[[ATTR9:[0-9]+]] { 339; CHECK-NEXT: call void @call_of_mystery() 340; CHECK-NEXT: ret void 341; 342 call void @call_of_mystery() 343 ret void 344} 345 346define void @daz_dapz_ieee_dapz() #12 { 347; CHECK-LABEL: define void @daz_dapz_ieee_dapz 348; CHECK-SAME: () #[[ATTR9]] { 349; CHECK-NEXT: call void @leaf_daz_dynamic_dynamic_dapz_from_daz_dapz_ieee_dapz() 350; CHECK-NEXT: ret void 351; 352 call void @leaf_daz_dynamic_dynamic_dapz_from_daz_dapz_ieee_dapz() 353 ret void 354} 355 356attributes #0 = { "denormal-fp-math"="dynamic,dynamic" } 357attributes #1 = { "denormal-fp-math-f32"="dynamic,dynamic" } 358attributes #2 = { "denormal-fp-math"="ieee,ieee" } 359attributes #3 = { "denormal-fp-math"="preserve-sign,preserve-sign" } 360attributes #4 = { "denormal-fp-math"="positive-zero,positive-zero" } 361attributes #5 = { "denormal-fp-math"="dynamic,dynamic" "denormal-fp-math-f32"="preserve-sign,preserve-sign" } 362attributes #6 = { "denormal-fp-math"="dynamic,ieee" } 363attributes #7 = { "denormal-fp-math"="ieee,dynamic" } 364attributes #8 = { "denormal-fp-math"="preserve-sign,dynamic" } 365attributes #9 = { "denormal-fp-math-f32"="preserve-sign,preserve-sign" } 366attributes #10 = { "denormal-fp-math"="preserve-sign,preserve-sign" "denormal-fp-math-f32"="ieee,ieee" } 367attributes #11 = { "denormal-fp-math"="preserve-sign,dynamic" "denormal-fp-math-f32"="dynamic,positive-zero" } 368attributes #12 = { "denormal-fp-math"="preserve-sign,positive-zero" "denormal-fp-math-f32"="ieee,positive-zero" } 369;. 370; CHECK: attributes #[[ATTR0]] = { "denormal-fp-math"="preserve-sign,preserve-sign" } 371; CHECK: attributes #[[ATTR1]] = { "denormal-fp-math-f32"="dynamic,dynamic" } 372; CHECK: attributes #[[ATTR2]] = { "denormal-fp-math"="dynamic,dynamic" } 373; CHECK: attributes #[[ATTR3]] = { "denormal-fp-math"="positive-zero,positive-zero" } 374; CHECK: attributes #[[ATTR4]] = { "denormal-fp-math"="dynamic,dynamic" "denormal-fp-math-f32"="preserve-sign,preserve-sign" } 375; CHECK: attributes #[[ATTR5]] = { "denormal-fp-math"="preserve-sign,ieee" } 376; CHECK: attributes #[[ATTR6]] = { "denormal-fp-math"="dynamic,ieee" } 377; CHECK: attributes #[[ATTR7]] = { "denormal-fp-math-f32"="preserve-sign,preserve-sign" } 378; CHECK: attributes #[[ATTR8]] = { "denormal-fp-math"="preserve-sign,preserve-sign" "denormal-fp-math-f32"="ieee,ieee" } 379; CHECK: attributes #[[ATTR9]] = { "denormal-fp-math"="preserve-sign,positive-zero" "denormal-fp-math-f32"="ieee,positive-zero" } 380;. 381