230 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; Replace a 'select' with 'or' in 'select - cmp [eq|ne] - br' sequence3; RUN: opt -passes=instcombine -S < %s | FileCheck %s4 5%struct.S = type { ptr, i32, i32 }6%C = type <{ %struct.S }>7 8declare void @bar(ptr)9declare void @foobar()10 11define void @test1(ptr %arg) {12; CHECK-LABEL: @test1(13; CHECK-NEXT: entry:14; CHECK-NEXT: [[M:%.*]] = load ptr, ptr [[ARG:%.*]], align 815; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG]], i64 1616; CHECK-NEXT: [[N:%.*]] = load ptr, ptr [[TMP1]], align 817; CHECK-NEXT: [[TMP5_NOT:%.*]] = icmp eq ptr [[M]], [[N]]18; CHECK-NEXT: br i1 [[TMP5_NOT]], label [[BB8:%.*]], label [[BB10:%.*]]19; CHECK: bb:20; CHECK-NEXT: ret void21; CHECK: bb8:22; CHECK-NEXT: tail call void @bar(ptr nonnull [[ARG]])23; CHECK-NEXT: br label [[BB:%.*]]24; CHECK: bb10:25; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[M]], i64 7226; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP2]], align 827; CHECK-NEXT: [[TMP11:%.*]] = tail call i64 [[TMP4]](ptr nonnull [[ARG]])28; CHECK-NEXT: br label [[BB]]29;30entry:31 %m = load ptr, ptr %arg, align 832 %tmp1 = getelementptr inbounds %C, ptr %arg, i64 1, i32 0, i32 033 %n = load ptr, ptr %tmp1, align 834 %tmp2 = getelementptr inbounds i64, ptr %m, i64 935 %tmp4 = load ptr, ptr %tmp2, align 836 %tmp5 = icmp eq ptr %m, %n37 %tmp6 = select i1 %tmp5, ptr %arg, ptr null38 %tmp7 = icmp eq ptr %tmp6, null39 br i1 %tmp7, label %bb10, label %bb840 41bb: ; preds = %bb10, %bb842 ret void43 44bb8: ; preds = %entry45 tail call void @bar(ptr %tmp6)46 br label %bb47 48bb10: ; preds = %entry49 %tmp11 = tail call i64 %tmp4(ptr %arg)50 br label %bb51}52 53define void @test2(ptr %arg) {54; CHECK-LABEL: @test2(55; CHECK-NEXT: entry:56; CHECK-NEXT: [[M:%.*]] = load ptr, ptr [[ARG:%.*]], align 857; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG]], i64 1658; CHECK-NEXT: [[N:%.*]] = load ptr, ptr [[TMP1]], align 859; CHECK-NEXT: [[TMP5:%.*]] = icmp eq ptr [[M]], [[N]]60; CHECK-NEXT: br i1 [[TMP5]], label [[BB10:%.*]], label [[BB8:%.*]]61; CHECK: bb:62; CHECK-NEXT: ret void63; CHECK: bb8:64; CHECK-NEXT: tail call void @bar(ptr nonnull [[ARG]])65; CHECK-NEXT: br label [[BB:%.*]]66; CHECK: bb10:67; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[M]], i64 7268; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP2]], align 869; CHECK-NEXT: [[TMP11:%.*]] = tail call i64 [[TMP4]](ptr nonnull [[ARG]])70; CHECK-NEXT: br label [[BB]]71;72entry:73 %m = load ptr, ptr %arg, align 874 %tmp1 = getelementptr inbounds %C, ptr %arg, i64 1, i32 0, i32 075 %n = load ptr, ptr %tmp1, align 876 %tmp2 = getelementptr inbounds i64, ptr %m, i64 977 %tmp4 = load ptr, ptr %tmp2, align 878 %tmp5 = icmp eq ptr %m, %n79 %tmp6 = select i1 %tmp5, ptr null, ptr %arg80 %tmp7 = icmp eq ptr %tmp6, null81 br i1 %tmp7, label %bb10, label %bb882 83bb: ; preds = %bb10, %bb884 ret void85 86bb8: ; preds = %entry87 tail call void @bar(ptr %tmp6)88 br label %bb89 90bb10: ; preds = %entry91 %tmp11 = tail call i64 %tmp4(ptr %arg)92 br label %bb93}94 95define void @test3(ptr %arg) {96; CHECK-LABEL: @test3(97; CHECK-NEXT: entry:98; CHECK-NEXT: [[M:%.*]] = load ptr, ptr [[ARG:%.*]], align 899; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG]], i64 16100; CHECK-NEXT: [[N:%.*]] = load ptr, ptr [[TMP1]], align 8101; CHECK-NEXT: [[TMP5:%.*]] = icmp eq ptr [[M]], [[N]]102; CHECK-NEXT: br i1 [[TMP5]], label [[BB8:%.*]], label [[BB10:%.*]]103; CHECK: bb:104; CHECK-NEXT: ret void105; CHECK: bb8:106; CHECK-NEXT: tail call void @bar(ptr nonnull [[ARG]])107; CHECK-NEXT: br label [[BB:%.*]]108; CHECK: bb10:109; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[M]], i64 72110; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP2]], align 8111; CHECK-NEXT: [[TMP11:%.*]] = tail call i64 [[TMP4]](ptr nonnull [[ARG]])112; CHECK-NEXT: br label [[BB]]113;114entry:115 %m = load ptr, ptr %arg, align 8116 %tmp1 = getelementptr inbounds %C, ptr %arg, i64 1, i32 0, i32 0117 %n = load ptr, ptr %tmp1, align 8118 %tmp2 = getelementptr inbounds i64, ptr %m, i64 9119 %tmp4 = load ptr, ptr %tmp2, align 8120 %tmp5 = icmp eq ptr %m, %n121 %tmp6 = select i1 %tmp5, ptr %arg, ptr null122 %tmp7 = icmp ne ptr %tmp6, null123 br i1 %tmp7, label %bb8, label %bb10124 125bb: ; preds = %bb10, %bb8126 ret void127 128bb8: ; preds = %entry129 tail call void @bar(ptr %tmp6)130 br label %bb131 132bb10: ; preds = %entry133 %tmp11 = tail call i64 %tmp4(ptr %arg)134 br label %bb135}136 137define void @test4(ptr %arg) {138; CHECK-LABEL: @test4(139; CHECK-NEXT: entry:140; CHECK-NEXT: [[M:%.*]] = load ptr, ptr [[ARG:%.*]], align 8141; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG]], i64 16142; CHECK-NEXT: [[N:%.*]] = load ptr, ptr [[TMP1]], align 8143; CHECK-NEXT: [[TMP5:%.*]] = icmp eq ptr [[M]], [[N]]144; CHECK-NEXT: br i1 [[TMP5]], label [[BB10:%.*]], label [[BB8:%.*]]145; CHECK: bb:146; CHECK-NEXT: ret void147; CHECK: bb8:148; CHECK-NEXT: tail call void @bar(ptr nonnull [[ARG]])149; CHECK-NEXT: br label [[BB:%.*]]150; CHECK: bb10:151; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[M]], i64 72152; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP2]], align 8153; CHECK-NEXT: [[TMP11:%.*]] = tail call i64 [[TMP4]](ptr nonnull [[ARG]])154; CHECK-NEXT: br label [[BB]]155;156entry:157 %m = load ptr, ptr %arg, align 8158 %tmp1 = getelementptr inbounds %C, ptr %arg, i64 1, i32 0, i32 0159 %n = load ptr, ptr %tmp1, align 8160 %tmp2 = getelementptr inbounds i64, ptr %m, i64 9161 %tmp4 = load ptr, ptr %tmp2, align 8162 %tmp5 = icmp eq ptr %m, %n163 %tmp6 = select i1 %tmp5, ptr null, ptr %arg164 %tmp7 = icmp ne ptr %tmp6, null165 br i1 %tmp7, label %bb8, label %bb10166 167bb: ; preds = %bb10, %bb8168 ret void169 170bb8: ; preds = %entry171 tail call void @bar(ptr %tmp6)172 br label %bb173 174bb10: ; preds = %entry175 %tmp11 = tail call i64 %tmp4(ptr %arg)176 br label %bb177}178 179define void @test5(ptr %arg, i1 %arg1) {180; CHECK-LABEL: @test5(181; CHECK-NEXT: entry:182; CHECK-NEXT: [[TMP2_NOT1:%.*]] = icmp eq ptr [[ARG:%.*]], null183; CHECK-NEXT: [[TMP2_NOT:%.*]] = select i1 [[ARG1:%.*]], i1 true, i1 [[TMP2_NOT1]]184; CHECK-NEXT: br i1 [[TMP2_NOT]], label [[BB5:%.*]], label [[BB3:%.*]]185; CHECK: bb:186; CHECK-NEXT: ret void187; CHECK: bb3:188; CHECK-NEXT: tail call void @bar(ptr [[ARG]])189; CHECK-NEXT: br label [[BB:%.*]]190; CHECK: bb5:191; CHECK-NEXT: tail call void @foobar()192; CHECK-NEXT: br label [[BB]]193;194entry:195 %tmp = select i1 %arg1, ptr null, ptr %arg196 %tmp2 = icmp ne ptr %tmp, null197 br i1 %tmp2, label %bb3, label %bb5198 199bb: ; preds = %bb5, %bb3200 ret void201 202bb3: ; preds = %entry203 tail call void @bar(ptr %tmp)204 br label %bb205 206bb5: ; preds = %entry207 tail call void @foobar()208 br label %bb209}210 211; Negative test. Must not trigger the select-cmp-br combine because the result212; of the select is used in both flows following the br (the special case where213; the conditional branch has the same target for both flows).214define i32 @test6(i32 %arg, i1 %arg1) {215; CHECK-LABEL: @test6(216; CHECK-NEXT: entry:217; CHECK-NEXT: br i1 false, label [[BB:%.*]], label [[BB]]218; CHECK: bb:219; CHECK-NEXT: [[TMP:%.*]] = select i1 [[ARG1:%.*]], i32 [[ARG:%.*]], i32 0220; CHECK-NEXT: ret i32 [[TMP]]221;222entry:223 %tmp = select i1 %arg1, i32 %arg, i32 0224 %tmp2 = icmp eq i32 %tmp, 0225 br i1 %tmp2, label %bb, label %bb226 227bb: ; preds = %entry, %entry228 ret i32 %tmp229}230