273 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 52; RUN: opt -S -passes=early-cse < %s | FileCheck %s3 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]]) #[[ATTR1:[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) readnone21 %c0 = call i8 @baz(i8 %x, i8 noundef %y) readnone22 %r = call i8 @buz(i8 %c0, i8 %c1)23 ret i8 %r24 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]]) #[[ATTR1]]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) readnone35 %c0 = call ptr @baz.ptr(i8 %x, i8 noundef %y) readnone36 %r = call i8 @buz.ptr(ptr %c0, ptr %c1)37 ret i8 %r38 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]]) #[[ATTR2:[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) readonly49 %c0 = call nnan float @baz.fp(float %x, float noundef %y) readonly50 %r = call i8 @buz.fp(float %c0, float %c1)51 ret i8 %r52 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]]) #[[ATTR1]]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) readnone63 %c0 = call nnan nsz float @baz.fp(float %x, float noundef %y) readnone64 %r = call i8 @buz.fp(float %c0, float %c1)65 ret i8 %r66 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]]) #[[ATTR2]]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) readonly77 %c0 = call ptr @baz.ptr(i8 %x, i8 noundef %y) readonly78 %r = call i8 @buz.ptr(ptr %c0, ptr %c1)79 ret i8 %r80 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]]) #[[ATTR2]]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) readonly91 %c0 = call ptr @baz.ptr(i8 %x, i8 noundef %y) readonly92 %r = call i8 @buz.ptr(ptr %c0, ptr noundef %c1)93 ret i8 %r94 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 %r109 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]]) #[[ATTR1]]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) readnone121 %c0 = call i8 @baz(i8 %x, i8 noundef %y)122 %r = call i8 @buz(i8 %c0, i8 %c1)123 ret i8 %r124 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]]) #[[ATTR1]]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]]) #[[ATTR2]]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]], 4138; CHECK-NEXT: ret i8 [[R2]]139;140 %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone141 br i1 %c, label %T, label %F142T:143 %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readonly144 %r = call i8 @buz(i8 %c0, i8 %c1)145 ret i8 %r146F:147 %r2 = add i8 %c1, 4148 ret i8 %r2149}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]]) #[[ATTR2]]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 9161;162 %c1 = call nonnull ptr @baz.ptr(i8 %x, i8 noundef %y) readonly163 br i1 %c, label %T, label %F164T:165 %c0 = call nonnull ptr @baz.ptr(i8 noundef %x, i8 noundef %y) readonly166 %r = call i8 @buz.ptr(ptr %c0, ptr noundef %c1)167 ret i8 %r168F:169 ret i8 9170}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]]) #[[ATTR1]]176; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR3:[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) readnone181 %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone alwaysinline182 %r = call i8 @buz(i8 %c0, i8 %c1)183 ret i8 %r184 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]]) #[[ATTR1]]191; CHECK-NEXT: [[C0:%.*]] = call i8 @baz(i8 noundef [[X]], i8 noundef [[Y]]) #[[ATTR4:[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) readnone196 %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone strictfp197 %r = call i8 @buz(i8 %c0, i8 %c1)198 ret i8 %r199 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]]) #[[ATTR1]]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]]) #[[ATTR5:[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]], 4213; CHECK-NEXT: ret i8 [[R2]]214;215 %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone216 br i1 %c, label %T, label %F217T:218 %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone optnone noinline219 %r = call i8 @buz(i8 %c0, i8 %c1)220 ret i8 %r221F:222 %r2 = add i8 %c1, 4223 ret i8 %r2224}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]]) #[[ATTR1]]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]]) #[[ATTR4]]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]], 4237; CHECK-NEXT: ret i8 [[R2]]238;239 %c1 = call i8 @baz(i8 %x, i8 noundef %y) readnone240 br i1 %c, label %T, label %F241T:242 %c0 = call i8 @baz(i8 noundef %x, i8 noundef %y) readnone strictfp243 %r = call i8 @buz(i8 %c0, i8 %c1)244 ret i8 %r245F:246 %r2 = add i8 %c1, 4247 ret i8 %r2248}249 250define i32 @commutative_intrinsic_intersection_failure(i32 %arg, i32 %arg1) {251; CHECK-LABEL: define i32 @commutative_intrinsic_intersection_failure(252; CHECK-SAME: i32 [[ARG:%.*]], i32 [[ARG1:%.*]]) {253; CHECK-NEXT: [[CALL:%.*]] = call i32 @llvm.smin.i32(i32 [[ARG]], i32 [[ARG1]]) #[[ATTR6:[0-9]+]]254; CHECK-NEXT: [[CALL2:%.*]] = call i32 @llvm.smin.i32(i32 [[ARG1]], i32 [[ARG]])255; CHECK-NEXT: [[OR:%.*]] = or i32 [[CALL2]], [[CALL]]256; CHECK-NEXT: ret i32 [[OR]]257;258 %call = call i32 @llvm.smin.i32(i32 %arg, i32 %arg1) strictfp259 %call2 = call i32 @llvm.smin.i32(i32 %arg1, i32 %arg)260 %or = or i32 %call2, %call261 ret i32 %or262}263 264;.265; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }266; CHECK: attributes #[[ATTR1]] = { memory(none) }267; CHECK: attributes #[[ATTR2]] = { memory(read) }268; CHECK: attributes #[[ATTR3]] = { alwaysinline memory(none) }269; CHECK: attributes #[[ATTR4]] = { strictfp memory(none) }270; CHECK: attributes #[[ATTR5]] = { noinline optnone memory(none) }271; CHECK: attributes #[[ATTR6]] = { strictfp }272;.273