1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5 2; RUN: opt -S -passes=early-cse < %s | FileCheck %s 3 4declare i8 @baz(i8, i8) 5declare i8 @baz_side_effects(i8, i8) 6declare i8 @buz(i8, i8) 7 8declare ptr @baz.ptr(i8, i8) 9declare i8 @buz.ptr(ptr, ptr) 10 11declare float @baz.fp(float, float) 12declare i8 @buz.fp(float, float) 13define i8 @same_parent_combine_diff_attrs(i8 %x, i8 %y) { 14; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs( 15; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 16; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0:[0-9]+]] 17; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C1]], i8 [[C1]]) 18; CHECK-NEXT: ret i8 [[R]] 19; 20 %c1 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone 21 %c0 = call i8 @baz(i8 %x, i8 noundef %y) readnone 22 %r = call i8 @buz(i8 %c0, i8 %c1) 23 ret i8 %r 24 25} 26 27define i8 @same_parent_combine_diff_attrs_needs_intersect(i8 %x, i8 %y) { 28; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_needs_intersect( 29; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 30; CHECK-NEXT: [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]] 31; CHECK-NEXT: [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr [[C1]]) 32; CHECK-NEXT: ret i8 [[R]] 33; 34 %c1 = call nonnull ptr @baz.ptr(i8 noundef %x, i8 noundef %y) readnone 35 %c0 = call ptr @baz.ptr(i8 %x, i8 noundef %y) readnone 36 %r = call i8 @buz.ptr(ptr %c0, ptr %c1) 37 ret i8 %r 38 39} 40 41define i8 @same_parent_combine_diff_attrs_fmf(float %x, float %y) { 42; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_fmf( 43; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) { 44; CHECK-NEXT: [[C1:%.*]] = call nnan float @baz.fp(float [[X]], float noundef [[Y]]) #[[ATTR1:[0-9]+]] 45; CHECK-NEXT: [[R:%.*]] = call i8 @buz.fp(float [[C1]], float [[C1]]) 46; CHECK-NEXT: ret i8 [[R]] 47; 48 %c1 = call nnan nsz float @baz.fp(float noundef %x, float noundef %y) readonly 49 %c0 = call nnan float @baz.fp(float %x, float noundef %y) readonly 50 %r = call i8 @buz.fp(float %c0, float %c1) 51 ret i8 %r 52 53} 54 55define i8 @same_parent_combine_diff_attrs_fmf2(float %x, float %y) { 56; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_fmf2( 57; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) { 58; CHECK-NEXT: [[C1:%.*]] = call nnan float @baz.fp(float [[X]], float noundef [[Y]]) #[[ATTR0]] 59; CHECK-NEXT: [[R:%.*]] = call i8 @buz.fp(float [[C1]], float [[C1]]) 60; CHECK-NEXT: ret i8 [[R]] 61; 62 %c1 = call nnan float @baz.fp(float noundef %x, float noundef %y) readnone 63 %c0 = call nnan nsz float @baz.fp(float %x, float noundef %y) readnone 64 %r = call i8 @buz.fp(float %c0, float %c1) 65 ret i8 %r 66 67} 68 69define i8 @same_parent_combine_diff_attrs_needs_intersect2(i8 %x, i8 %y) { 70; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_needs_intersect2( 71; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 72; CHECK-NEXT: [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]] 73; CHECK-NEXT: [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr [[C1]]) 74; CHECK-NEXT: ret i8 [[R]] 75; 76 %c1 = call nonnull ptr @baz.ptr(i8 noundef %x, i8 noundef %y) readonly 77 %c0 = call ptr @baz.ptr(i8 %x, i8 noundef %y) readonly 78 %r = call i8 @buz.ptr(ptr %c0, ptr %c1) 79 ret i8 %r 80 81} 82 83define i8 @same_parent_combine_diff_attrs_really_needs_intersect(i8 %x, i8 %y) { 84; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_really_needs_intersect( 85; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 86; CHECK-NEXT: [[C1:%.*]] = call ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]] 87; CHECK-NEXT: [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr noundef [[C1]]) 88; CHECK-NEXT: ret i8 [[R]] 89; 90 %c1 = call nonnull ptr @baz.ptr(i8 noundef %x, i8 noundef %y) readonly 91 %c0 = call ptr @baz.ptr(i8 %x, i8 noundef %y) readonly 92 %r = call i8 @buz.ptr(ptr %c0, ptr noundef %c1) 93 ret i8 %r 94 95} 96 97define i8 @same_parent_combine_diff_attrs_fail_side_effects(i8 %x, i8 %y) { 98; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_fail_side_effects( 99; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 100; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) 101; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) 102; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]]) 103; CHECK-NEXT: ret i8 [[R]] 104; 105 %c1 = call i8 @baz(i8 noundef %x, i8 noundef %y) 106 %c0 = call i8 @baz(i8 %x, i8 noundef %y) 107 %r = call i8 @buz(i8 %c0, i8 %c1) 108 ret i8 %r 109 110} 111 112define i8 @same_parent_combine_diff_attrs_quasi_side_effects2(i8 %x, i8 %y) { 113; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_quasi_side_effects2( 114; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 115; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR0]] 116; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) 117; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]]) 118; CHECK-NEXT: ret i8 [[R]] 119; 120 %c1 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone 121 %c0 = call i8 @baz(i8 %x, i8 noundef %y) 122 %r = call i8 @buz(i8 %c0, i8 %c1) 123 ret i8 %r 124 125} 126 127define i8 @diff_parent_combine_diff_attrs(i1 %c, i8 %x, i8 %y) { 128; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs( 129; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) { 130; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]] 131; CHECK-NEXT: br i1 [[C]], label %[[T:.*]], label %[[F:.*]] 132; CHECK: [[T]]: 133; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR1]] 134; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]]) 135; CHECK-NEXT: ret i8 [[R]] 136; CHECK: [[F]]: 137; CHECK-NEXT: [[R2:%.*]] = add i8 [[C1]], 4 138; CHECK-NEXT: ret i8 [[R2]] 139; 140 %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone 141 br i1 %c, label %T, label %F 142T: 143 %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readonly 144 %r = call i8 @buz(i8 %c0, i8 %c1) 145 ret i8 %r 146F: 147 %r2 = add i8 %c1, 4 148 ret i8 %r2 149} 150 151define i8 @diff_parent_combine_diff_attrs_preserves_return_attrs(i1 %c, i8 %x, i8 %y) { 152; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs_preserves_return_attrs( 153; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) { 154; CHECK-NEXT: [[C1:%.*]] = call nonnull ptr @baz.ptr(i8 [[X]], i8 noundef [[Y]]) #[[ATTR1]] 155; CHECK-NEXT: br i1 [[C]], label %[[T:.*]], label %[[F:.*]] 156; CHECK: [[T]]: 157; CHECK-NEXT: [[R:%.*]] = call i8 @buz.ptr(ptr [[C1]], ptr noundef [[C1]]) 158; CHECK-NEXT: ret i8 [[R]] 159; CHECK: [[F]]: 160; CHECK-NEXT: ret i8 9 161; 162 %c1 = call nonnull ptr @baz.ptr(i8 %x, i8 noundef %y) readonly 163 br i1 %c, label %T, label %F 164T: 165 %c0 = call nonnull ptr @baz.ptr(i8 noundef %x, i8 noundef %y) readonly 166 %r = call i8 @buz.ptr(ptr %c0, ptr noundef %c1) 167 ret i8 %r 168F: 169 ret i8 9 170} 171 172define i8 @same_parent_combine_diff_attrs_todo(i8 %x, i8 %y) { 173; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_todo( 174; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 175; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]] 176; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR2:[0-9]+]] 177; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]]) 178; CHECK-NEXT: ret i8 [[R]] 179; 180 %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone 181 %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone alwaysinline 182 %r = call i8 @buz(i8 %c0, i8 %c1) 183 ret i8 %r 184 185} 186 187define i8 @same_parent_combine_diff_attrs_fail(i8 %x, i8 %y) { 188; CHECK-LABEL: define i8 @same_parent_combine_diff_attrs_fail( 189; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 190; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]] 191; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR3:[0-9]+]] 192; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]]) 193; CHECK-NEXT: ret i8 [[R]] 194; 195 %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone 196 %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone strictfp 197 %r = call i8 @buz(i8 %c0, i8 %c1) 198 ret i8 %r 199 200} 201 202define i8 @diff_parent_combine_diff_attrs_todo(i1 %c, i8 %x, i8 %y) { 203; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs_todo( 204; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) { 205; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]] 206; CHECK-NEXT: br i1 [[C]], label %[[T:.*]], label %[[F:.*]] 207; CHECK: [[T]]: 208; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR4:[0-9]+]] 209; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]]) 210; CHECK-NEXT: ret i8 [[R]] 211; CHECK: [[F]]: 212; CHECK-NEXT: [[R2:%.*]] = add i8 [[C1]], 4 213; CHECK-NEXT: ret i8 [[R2]] 214; 215 %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone 216 br i1 %c, label %T, label %F 217T: 218 %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone optnone noinline 219 %r = call i8 @buz(i8 %c0, i8 %c1) 220 ret i8 %r 221F: 222 %r2 = add i8 %c1, 4 223 ret i8 %r2 224} 225 226define i8 @diff_parent_combine_diff_attrs_fail(i1 %c, i8 %x, i8 %y) { 227; CHECK-LABEL: define i8 @diff_parent_combine_diff_attrs_fail( 228; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) { 229; CHECK-NEXT: [[C1:%.*]] = call i8 @baz(i8 [[X]], i8 noundef [[Y]]) #[[ATTR0]] 230; CHECK-NEXT: br i1 [[C]], label %[[T:.*]], label %[[F:.*]] 231; CHECK: [[T]]: 232; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR3]] 233; CHECK-NEXT: [[R:%.*]] = call i8 @buz(i8 [[C0]], i8 [[C1]]) 234; CHECK-NEXT: ret i8 [[R]] 235; CHECK: [[F]]: 236; CHECK-NEXT: [[R2:%.*]] = add i8 [[C1]], 4 237; CHECK-NEXT: ret i8 [[R2]] 238; 239 %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone 240 br i1 %c, label %T, label %F 241T: 242 %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone strictfp 243 %r = call i8 @buz(i8 %c0, i8 %c1) 244 ret i8 %r 245F: 246 %r2 = add i8 %c1, 4 247 ret i8 %r2 248} 249 250;. 251; CHECK: attributes #[[ATTR0]] = { memory(none) } 252; CHECK: attributes #[[ATTR1]] = { memory(read) } 253; CHECK: attributes #[[ATTR2]] = { alwaysinline memory(none) } 254; CHECK: attributes #[[ATTR3]] = { strictfp memory(none) } 255; CHECK: attributes #[[ATTR4]] = { noinline optnone memory(none) } 256;. 257