1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals 2; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=22 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM 3; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=20 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM 4; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM 5; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM 6 7; FIXME: CGSCC is not looking at callees and calleers even though it could be allowed. 8 9define i32 @test0(i32* %p) { 10; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 11; CHECK-LABEL: define {{[^@]+}}@test0 12; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0:[0-9]+]] { 13; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, !range [[RNG0:![0-9]+]] 14; CHECK-NEXT: ret i32 [[A]] 15; 16 %a = load i32, i32* %p, !range !0 17 ret i32 %a 18} 19 20define i32 @test0-range-check(i32* %p) { 21; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 22; IS__TUNIT____-LABEL: define {{[^@]+}}@test0-range-check 23; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]]) #[[ATTR0]] { 24; IS__TUNIT____-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #[[ATTR3:[0-9]+]], !range [[RNG0]] 25; IS__TUNIT____-NEXT: ret i32 [[A]] 26; 27; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 28; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-range-check 29; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0]] { 30; IS__CGSCC____-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR3:[0-9]+]], !range [[RNG0]] 31; IS__CGSCC____-NEXT: ret i32 [[A]] 32; 33 %a = tail call i32 @test0(i32* %p) 34 ret i32 %a 35} 36 37declare void @use3-dummy(i1, i1, i1) 38define void @use3(i1, i1, i1) { 39; CHECK-LABEL: define {{[^@]+}}@use3 40; CHECK-SAME: (i1 [[TMP0:%.*]], i1 [[TMP1:%.*]], i1 [[TMP2:%.*]]) { 41; CHECK-NEXT: tail call void @use3-dummy(i1 [[TMP0]], i1 [[TMP1]], i1 [[TMP2]]) 42; CHECK-NEXT: ret void 43; 44 tail call void @use3-dummy(i1 %0, i1 %1, i1 %2) 45 ret void 46} 47 48; TEST0 icmp test 49define void @test0-icmp-check(i32* %p){ 50 ; ret = [0, 10) 51; IS__TUNIT____-LABEL: define {{[^@]+}}@test0-icmp-check 52; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]]) { 53; IS__TUNIT____-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #[[ATTR3]], !range [[RNG0]] 54; IS__TUNIT____-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9 55; IS__TUNIT____-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8 56; IS__TUNIT____-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1 57; IS__TUNIT____-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0 58; IS__TUNIT____-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]]) 59; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 noundef false) 60; IS__TUNIT____-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9 61; IS__TUNIT____-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8 62; IS__TUNIT____-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1 63; IS__TUNIT____-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0 64; IS__TUNIT____-NEXT: tail call void @use3(i1 noundef true, i1 [[CMP_NE_2]], i1 [[CMP_NE_3]]) 65; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 noundef true) 66; IS__TUNIT____-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8 67; IS__TUNIT____-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1 68; IS__TUNIT____-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0 69; IS__TUNIT____-NEXT: tail call void @use3(i1 noundef false, i1 noundef false, i1 [[CMP_UGT_3]]) 70; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false) 71; IS__TUNIT____-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9 72; IS__TUNIT____-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8 73; IS__TUNIT____-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1 74; IS__TUNIT____-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) 75; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 noundef false) 76; IS__TUNIT____-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8 77; IS__TUNIT____-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1 78; IS__TUNIT____-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0 79; IS__TUNIT____-NEXT: tail call void @use3(i1 noundef false, i1 noundef false, i1 [[CMP_SGT_3]]) 80; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 noundef true) 81; IS__TUNIT____-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9 82; IS__TUNIT____-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8 83; IS__TUNIT____-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1 84; IS__TUNIT____-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]]) 85; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 noundef true, i1 noundef true) 86; IS__TUNIT____-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9 87; IS__TUNIT____-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8 88; IS__TUNIT____-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1 89; IS__TUNIT____-NEXT: tail call void @use3(i1 noundef true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]]) 90; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 noundef false, i1 noundef false) 91; IS__TUNIT____-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8 92; IS__TUNIT____-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1 93; IS__TUNIT____-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0 94; IS__TUNIT____-NEXT: tail call void @use3(i1 noundef true, i1 noundef true, i1 [[CMP_LTE_3]]) 95; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 noundef false) 96; IS__TUNIT____-NEXT: ret void 97; 98; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-icmp-check 99; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) { 100; IS__CGSCC____-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR3]], !range [[RNG0]] 101; IS__CGSCC____-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9 102; IS__CGSCC____-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8 103; IS__CGSCC____-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1 104; IS__CGSCC____-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0 105; IS__CGSCC____-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]]) 106; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 noundef false) 107; IS__CGSCC____-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9 108; IS__CGSCC____-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8 109; IS__CGSCC____-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1 110; IS__CGSCC____-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0 111; IS__CGSCC____-NEXT: tail call void @use3(i1 noundef true, i1 [[CMP_NE_2]], i1 [[CMP_NE_3]]) 112; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 noundef true) 113; IS__CGSCC____-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8 114; IS__CGSCC____-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1 115; IS__CGSCC____-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0 116; IS__CGSCC____-NEXT: tail call void @use3(i1 noundef false, i1 noundef false, i1 [[CMP_UGT_3]]) 117; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false) 118; IS__CGSCC____-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9 119; IS__CGSCC____-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8 120; IS__CGSCC____-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1 121; IS__CGSCC____-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) 122; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 noundef false) 123; IS__CGSCC____-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8 124; IS__CGSCC____-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1 125; IS__CGSCC____-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0 126; IS__CGSCC____-NEXT: tail call void @use3(i1 noundef false, i1 noundef false, i1 [[CMP_SGT_3]]) 127; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 noundef true) 128; IS__CGSCC____-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9 129; IS__CGSCC____-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8 130; IS__CGSCC____-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1 131; IS__CGSCC____-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]]) 132; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 noundef true, i1 noundef true) 133; IS__CGSCC____-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9 134; IS__CGSCC____-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8 135; IS__CGSCC____-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1 136; IS__CGSCC____-NEXT: tail call void @use3(i1 noundef true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]]) 137; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 noundef false, i1 noundef false) 138; IS__CGSCC____-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8 139; IS__CGSCC____-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1 140; IS__CGSCC____-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0 141; IS__CGSCC____-NEXT: tail call void @use3(i1 noundef true, i1 noundef true, i1 [[CMP_LTE_3]]) 142; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 noundef false) 143; IS__CGSCC____-NEXT: ret void 144; 145 %ret = tail call i32 @test0(i32 *%p) 146 147 ; ret = [0, 10), eq 148 %cmp-eq-1 = icmp eq i32 %ret, 10 149 %cmp-eq-2 = icmp eq i32 %ret, 9 150 %cmp-eq-3 = icmp eq i32 %ret, 8 151 %cmp-eq-4 = icmp eq i32 %ret, 1 152 %cmp-eq-5 = icmp eq i32 %ret, 0 153 %cmp-eq-6 = icmp eq i32 %ret, -1 154 tail call void @use3(i1 %cmp-eq-1, i1 %cmp-eq-2, i1 %cmp-eq-3) 155 tail call void @use3(i1 %cmp-eq-4, i1 %cmp-eq-5, i1 %cmp-eq-6) 156 157 ; ret = [0, 10), ne 158 %cmp-ne-1 = icmp ne i32 %ret, 10 159 %cmp-ne-2 = icmp ne i32 %ret, 9 160 %cmp-ne-3 = icmp ne i32 %ret, 8 161 %cmp-ne-4 = icmp ne i32 %ret, 1 162 %cmp-ne-5 = icmp ne i32 %ret, 0 163 %cmp-ne-6 = icmp ne i32 %ret, -1 164 tail call void @use3(i1 %cmp-ne-1, i1 %cmp-ne-2, i1 %cmp-ne-3) 165 tail call void @use3(i1 %cmp-ne-4, i1 %cmp-ne-5, i1 %cmp-ne-6) 166 167 ; ret = [0, 10), ugt 168 %cmp-ugt-1 = icmp ugt i32 %ret, 10 169 %cmp-ugt-2 = icmp ugt i32 %ret, 9 170 %cmp-ugt-3 = icmp ugt i32 %ret, 8 171 %cmp-ugt-4 = icmp ugt i32 %ret, 1 172 %cmp-ugt-5 = icmp ugt i32 %ret, 0 173 %cmp-ugt-6 = icmp ugt i32 %ret, -1 174 tail call void @use3(i1 %cmp-ugt-1, i1 %cmp-ugt-2, i1 %cmp-ugt-3) 175 tail call void @use3(i1 %cmp-ugt-4, i1 %cmp-ugt-5, i1 %cmp-ugt-6) 176 177 ; ret = [0, 10), uge 178 %cmp-uge-1 = icmp uge i32 %ret, 10 179 %cmp-uge-2 = icmp uge i32 %ret, 9 180 %cmp-uge-3 = icmp uge i32 %ret, 8 181 %cmp-uge-4 = icmp uge i32 %ret, 1 182 %cmp-uge-5 = icmp uge i32 %ret, 0 183 %cmp-uge-6 = icmp uge i32 %ret, -1 184 tail call void @use3(i1 %cmp-uge-1, i1 %cmp-uge-2, i1 %cmp-uge-3) 185 tail call void @use3(i1 %cmp-uge-4, i1 %cmp-uge-5, i1 %cmp-uge-6) 186 187 ; ret = [0, 10), sgt 188 %cmp-sgt-1 = icmp sgt i32 %ret, 10 189 %cmp-sgt-2 = icmp sgt i32 %ret, 9 190 %cmp-sgt-3 = icmp sgt i32 %ret, 8 191 %cmp-sgt-4 = icmp sgt i32 %ret, 1 192 %cmp-sgt-5 = icmp sgt i32 %ret, 0 193 %cmp-sgt-6 = icmp sgt i32 %ret, -1 194 tail call void @use3(i1 %cmp-sgt-1, i1 %cmp-sgt-2, i1 %cmp-sgt-3) 195 tail call void @use3(i1 %cmp-sgt-4, i1 %cmp-sgt-5, i1 %cmp-sgt-6) 196 197 ; ret = [0, 10), sge 198 %cmp-gte-1 = icmp sge i32 %ret, 10 199 %cmp-gte-2 = icmp sge i32 %ret, 9 200 %cmp-gte-3 = icmp sge i32 %ret, 8 201 %cmp-gte-4 = icmp sge i32 %ret, 1 202 %cmp-gte-5 = icmp sge i32 %ret, 0 203 %cmp-gte-6 = icmp sge i32 %ret, -1 204 tail call void @use3(i1 %cmp-gte-1, i1 %cmp-gte-2, i1 %cmp-gte-3) 205 tail call void @use3(i1 %cmp-gte-4, i1 %cmp-gte-5, i1 %cmp-gte-6) 206 207 ; ret = [0, 10), slt 208 %cmp-slt-1 = icmp slt i32 %ret, 10 209 %cmp-slt-2 = icmp slt i32 %ret, 9 210 %cmp-slt-3 = icmp slt i32 %ret, 8 211 %cmp-slt-4 = icmp slt i32 %ret, 1 212 %cmp-slt-5 = icmp slt i32 %ret, 0 213 %cmp-slt-6 = icmp slt i32 %ret, -1 214 tail call void @use3(i1 %cmp-slt-1, i1 %cmp-slt-2, i1 %cmp-slt-3) 215 tail call void @use3(i1 %cmp-slt-4, i1 %cmp-slt-5, i1 %cmp-slt-6) 216 217 ; ret = [0, 10), sle 218 %cmp-lte-1 = icmp sle i32 %ret, 10 219 %cmp-lte-2 = icmp sle i32 %ret, 9 220 %cmp-lte-3 = icmp sle i32 %ret, 8 221 %cmp-lte-4 = icmp sle i32 %ret, 1 222 %cmp-lte-5 = icmp sle i32 %ret, 0 223 %cmp-lte-6 = icmp sle i32 %ret, -1 224 tail call void @use3(i1 %cmp-lte-1, i1 %cmp-lte-2, i1 %cmp-lte-3) 225 tail call void @use3(i1 %cmp-lte-4, i1 %cmp-lte-5, i1 %cmp-lte-6) 226 227 ret void 228} 229define i32 @test1(i32* %p) { 230; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 231; CHECK-LABEL: define {{[^@]+}}@test1 232; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0]] { 233; CHECK-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, !range [[RNG1:![0-9]+]] 234; CHECK-NEXT: [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10 235; CHECK-NEXT: [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10 236; CHECK-NEXT: ret i32 [[MUL_10_THEN_200_1091]] 237; 238 %load-10-100 = load i32, i32* %p, !range !1 239 %add-10-then-20-110 = add i32 %load-10-100, 10 240 %mul-10-then-200-1091 = mul i32 %add-10-then-20-110, 10 241 ret i32 %mul-10-then-200-1091 242} 243 244define i1 @test1-check(i32* %p) { 245; 246; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 247; IS__TUNIT____-LABEL: define {{[^@]+}}@test1-check 248; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]]) #[[ATTR0]] { 249; IS__TUNIT____-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) #[[ATTR3]], !range [[RNG2:![0-9]+]] 250; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 251; IS__TUNIT____-NEXT: ret i1 [[CMP]] 252; 253; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 254; IS__CGSCC____-LABEL: define {{[^@]+}}@test1-check 255; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0]] { 256; IS__CGSCC____-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR3]], !range [[RNG2:![0-9]+]] 257; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 258; IS__CGSCC____-NEXT: ret i1 [[CMP]] 259; 260 %res = tail call i32 @test1(i32* %p) 261 %cmp = icmp eq i32 %res, 500 262 ret i1 %cmp 263} 264 265; TEST2 266; int test2(int *p) { return *p == 0 ? 4 : 3; } 267; int test2_check(int *p) { 268; int call = test2(p); 269; if (call == 5) { 270; // dead block 271; return 2; 272; } else { 273; return 3; 274; } 275; } 276 277define i32 @test2(i32* %p) { 278; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 279; CHECK-LABEL: define {{[^@]+}}@test2 280; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0]] { 281; CHECK-NEXT: entry: 282; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 4 283; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 284; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 4, i32 3 285; CHECK-NEXT: ret i32 [[COND]] 286; 287entry: 288 %0 = load i32, i32* %p, align 4 289 %tobool = icmp eq i32 %0, 0 290 %cond = select i1 %tobool, i32 4, i32 3 291 ret i32 %cond 292} 293 294define i32 @test2_check(i32* %p) { 295; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 296; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_check 297; IS__TUNIT____-SAME: (i32* nocapture nofree readnone align 4 [[P:%.*]]) #[[ATTR1:[0-9]+]] { 298; IS__TUNIT____-NEXT: entry: 299; IS__TUNIT____-NEXT: br label [[IF_THEN:%.*]] 300; IS__TUNIT____: if.then: 301; IS__TUNIT____-NEXT: br label [[RETURN:%.*]] 302; IS__TUNIT____: if.end: 303; IS__TUNIT____-NEXT: unreachable 304; IS__TUNIT____: return: 305; IS__TUNIT____-NEXT: ret i32 2 306; 307; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 308; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_check 309; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readnone align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR1:[0-9]+]] { 310; IS__CGSCC____-NEXT: entry: 311; IS__CGSCC____-NEXT: br label [[IF_THEN:%.*]] 312; IS__CGSCC____: if.then: 313; IS__CGSCC____-NEXT: br label [[RETURN:%.*]] 314; IS__CGSCC____: if.end: 315; IS__CGSCC____-NEXT: unreachable 316; IS__CGSCC____: return: 317; IS__CGSCC____-NEXT: ret i32 2 318; 319entry: 320 %call = tail call i32 @test2(i32* %p) 321 %cmp = icmp slt i32 %call, 5 322 br i1 %cmp, label %if.then, label %if.end 323 324if.then: ; preds = %entry 325 br label %return 326 327if.end: ; preds = %entry 328 br label %return 329 330return: ; preds = %if.end, %if.then 331 %retval.0 = phi i32 [ 2, %if.then ], [ 3, %if.end ] 332 ret i32 %retval.0 333} 334 335; TEST 3 SECV test 336 337; void unkown(); 338; int r1(unsigned int u){ 339; int sum = 0; 340; for(int i = 0; i<100;i++){ 341; sum += i; 342; } 343; // sum = 50 * 49 / 2 344; if(sum > 10000){ 345; // dead block 346; return 20; 347; }else { 348; return 10; 349; } 350; } 351; void f1(int u){ 352; if(r1(u) > 15){ 353; // deadblock 354; unkown(); 355; }else { 356; return; 357; } 358; } 359 360declare dso_local void @unkown() 361 362define internal i32 @r1(i32) local_unnamed_addr { 363; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone 364; IS________OPM-LABEL: define {{[^@]+}}@r1 365; IS________OPM-SAME: () local_unnamed_addr #[[ATTR2:[0-9]+]] { 366; IS________OPM-NEXT: br label [[TMP4:%.*]] 367; IS________OPM: 1: 368; IS________OPM-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000 369; IS________OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]] 370; IS________OPM: 3: 371; IS________OPM-NEXT: ret i32 20 372; IS________OPM: f: 373; IS________OPM-NEXT: ret i32 10 374; IS________OPM: 4: 375; IS________OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ] 376; IS________OPM-NEXT: [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ] 377; IS________OPM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]] 378; IS________OPM-NEXT: [[TMP8]] = add nuw nsw i32 [[TMP5]], 1 379; IS________OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100 380; IS________OPM-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]] 381; 382; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 383; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@r1 384; IS__CGSCC_NPM-SAME: () local_unnamed_addr #[[ATTR1]] { 385; IS__CGSCC_NPM-NEXT: br label [[TMP3:%.*]] 386; IS__CGSCC_NPM: 1: 387; IS__CGSCC_NPM-NEXT: br label [[F:%.*]] 388; IS__CGSCC_NPM: 2: 389; IS__CGSCC_NPM-NEXT: unreachable 390; IS__CGSCC_NPM: f: 391; IS__CGSCC_NPM-NEXT: ret i32 10 392; IS__CGSCC_NPM: 3: 393; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP7:%.*]], [[TMP3]] ] 394; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP6:%.*]], [[TMP3]] ] 395; IS__CGSCC_NPM-NEXT: [[TMP6]] = add nuw nsw i32 [[TMP4]], [[TMP5]] 396; IS__CGSCC_NPM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP4]], 1 397; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 100 398; IS__CGSCC_NPM-NEXT: br i1 [[TMP8]], label [[TMP1:%.*]], label [[TMP3]] 399; 400 br label %5 401 4022: ; preds = %5 403 %3 = icmp sgt i32 %8, 10000 404 br i1 %3, label %4, label %f 4054: 406 ret i32 20 407f: 408 ret i32 10 4095: ; preds = %5, %1 410 %6 = phi i32 [ 0, %1 ], [ %9, %5 ] 411 %7 = phi i32 [ 0, %1 ], [ %8, %5 ] 412 %8 = add nuw nsw i32 %6, %7 413 %9 = add nuw nsw i32 %6, 1 414 %10 = icmp eq i32 %9, 100 415 br i1 %10, label %2, label %5 416} 417 418define void @f1(i32){ 419; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f1 420; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]]) { 421; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR4:[0-9]+]] 422; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15 423; IS__TUNIT_OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] 424; IS__TUNIT_OPM: 4: 425; IS__TUNIT_OPM-NEXT: tail call void @unkown() 426; IS__TUNIT_OPM-NEXT: br label [[TMP5]] 427; IS__TUNIT_OPM: 5: 428; IS__TUNIT_OPM-NEXT: ret void 429; 430; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 431; IS________NPM-LABEL: define {{[^@]+}}@f1 432; IS________NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { 433; IS________NPM-NEXT: br label [[TMP3:%.*]] 434; IS________NPM: 2: 435; IS________NPM-NEXT: unreachable 436; IS________NPM: 3: 437; IS________NPM-NEXT: ret void 438; 439; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1 440; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) { 441; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR4:[0-9]+]], !range [[RNG3:![0-9]+]] 442; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15 443; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] 444; IS__CGSCC_OPM: 4: 445; IS__CGSCC_OPM-NEXT: tail call void @unkown() 446; IS__CGSCC_OPM-NEXT: br label [[TMP5]] 447; IS__CGSCC_OPM: 5: 448; IS__CGSCC_OPM-NEXT: ret void 449; 450 %2 = tail call i32 @r1(i32 %0) 451 %3 = icmp sgt i32 %2, 15 452 br i1 %3, label %4, label %5 453 4544: ; preds = %1 455 tail call void @unkown() 456 br label %5 457 4585: ; preds = %1, %4 459 ret void 460} 461 462; TEST4 LVI test 463 464; f1 465; int test4-f1(int u){ 466; if(u>=0) { 467; return u; 468; }else{ 469; return 0; 470; } 471; } 472define dso_local i32 @test4-f1(i32 %u) { 473; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 474; CHECK-LABEL: define {{[^@]+}}@test4-f1 475; CHECK-SAME: (i32 [[U:%.*]]) #[[ATTR1:[0-9]+]] { 476; CHECK-NEXT: entry: 477; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 478; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] 479; CHECK: if.then: 480; CHECK-NEXT: br label [[RETURN]] 481; CHECK: return: 482; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ] 483; CHECK-NEXT: ret i32 [[RETVAL_0]] 484; 485; FIXME: RETVAL_0 >= 0 486entry: 487 %cmp = icmp sgt i32 %u, -1 488 br i1 %cmp, label %if.then, label %return 489 490if.then: ; preds = %entry 491 br label %return 492 493return: ; preds = %entry, %if.then 494 %retval.0 = phi i32 [ %u, %if.then ], [ 0, %entry ] 495 ret i32 %retval.0 496} 497 498 499define dso_local i32 @test4-g1(i32 %u) { 500; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 501; IS________OPM-LABEL: define {{[^@]+}}@test4-g1 502; IS________OPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { 503; IS________OPM-NEXT: entry: 504; IS________OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR5:[0-9]+]] 505; IS________OPM-NEXT: ret i32 [[CALL]] 506; 507; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 508; IS________NPM-LABEL: define {{[^@]+}}@test4-g1 509; IS________NPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { 510; IS________NPM-NEXT: entry: 511; IS________NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR4:[0-9]+]] 512; IS________NPM-NEXT: ret i32 [[CALL]] 513; 514; FIXME: %call should have range [0, inf] 515 516entry: 517 %call = tail call i32 @test4-f1(i32 %u) 518 ret i32 %call 519} 520 521; f2 522; int test4-f1(int u){ 523; if(u>-1) { 524; return u+1; 525; }else{ 526; return 1; 527; } 528; } 529define dso_local i32 @test4-f2(i32 %u) { 530; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 531; CHECK-LABEL: define {{[^@]+}}@test4-f2 532; CHECK-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { 533; CHECK-NEXT: entry: 534; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 535; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 536; CHECK: if.then: 537; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1 538; CHECK-NEXT: br label [[RETURN:%.*]] 539; CHECK: if.else: 540; CHECK-NEXT: br label [[RETURN]] 541; CHECK: return: 542; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ] 543; CHECK-NEXT: ret i32 [[RETVAL_0]] 544; 545entry: 546 %cmp = icmp sgt i32 %u, -1 547 br i1 %cmp, label %if.then, label %if.else 548 549if.then: ; preds = %entry 550 %add = add nuw nsw i32 %u, 1 551 br label %return 552 553if.else: ; preds = %entry 554 br label %return 555 556return: ; preds = %if.else, %if.then 557 %retval.0 = phi i32 [ %add, %if.then ], [ 1, %if.else ] 558 ret i32 %retval.0 559} 560 561 562define dso_local i32 @test4-g2(i32 %u) { 563; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 564; IS________OPM-LABEL: define {{[^@]+}}@test4-g2 565; IS________OPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { 566; IS________OPM-NEXT: entry: 567; IS________OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR5]] 568; IS________OPM-NEXT: ret i32 [[CALL]] 569; 570; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 571; IS________NPM-LABEL: define {{[^@]+}}@test4-g2 572; IS________NPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { 573; IS________NPM-NEXT: entry: 574; IS________NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR4]], !range [[RNG3:![0-9]+]] 575; IS________NPM-NEXT: ret i32 [[CALL]] 576; 577entry: 578 %call = tail call i32 @test4-f2(i32 %u) 579 ret i32 %call 580} 581 582define dso_local i32 @test-5() { 583; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test-5() { 584; IS__TUNIT_OPM-NEXT: entry: 585; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0), !range [[RNG3:![0-9]+]] 586; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]] 587; 588; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test-5() { 589; NOT_TUNIT_OPM-NEXT: entry: 590; NOT_TUNIT_OPM-NEXT: [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0), !range [[RNG4:![0-9]+]] 591; NOT_TUNIT_OPM-NEXT: ret i32 [[CALL]] 592; 593entry: 594 %call = call i32 @rec(i32 0) 595 ret i32 %call 596} 597define internal i32 @rec(i32 %depth) { 598; CHECK-LABEL: define {{[^@]+}}@rec 599; CHECK-SAME: (i32 [[DEPTH:%.*]]) { 600; CHECK-NEXT: entry: 601; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo(i32 [[DEPTH]]) 602; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[CALL]], 0 603; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 604; CHECK: if.then: 605; CHECK-NEXT: br label [[RETURN:%.*]] 606; CHECK: if.end: 607; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[DEPTH]], 10 608; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END3:%.*]] 609; CHECK: if.then1: 610; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[DEPTH]], 1 611; CHECK-NEXT: [[CALL2:%.*]] = call i32 @rec(i32 [[ADD]]) 612; CHECK-NEXT: br label [[IF_END3]] 613; CHECK: if.end3: 614; CHECK-NEXT: br label [[RETURN]] 615; CHECK: return: 616; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ 1, [[IF_END3]] ] 617; CHECK-NEXT: ret i32 [[RETVAL_0]] 618; 619entry: 620 %call = call i32 @foo(i32 %depth) 621 %tobool = icmp ne i32 %call, 0 622 br i1 %tobool, label %if.then, label %if.end 623 624if.then: ; preds = %entry 625 br label %return 626 627if.end: ; preds = %entry 628 %cmp = icmp slt i32 %depth, 10 629 br i1 %cmp, label %if.then1, label %if.end3 630 631if.then1: ; preds = %if.end 632 %add = add nsw i32 %depth, 1 633 %call2 = call i32 @rec(i32 %add) 634 br label %if.end3 635 636if.end3: ; preds = %if.then1, %if.end 637 br label %return 638 639return: ; preds = %if.end3, %if.then 640 %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.end3 ] 641 ret i32 %retval.0 642} 643declare dso_local i32 @foo(i32) 644 645 646; Examples taken from https://llvm.discourse.group/t/impossible-condition-optimization/461/1 647; 648; The important part is that we return a constant (false) 649; 650; { 651 652; FIXME: All but the return is not needed anymore 653define dso_local zeroext i1 @phi(i32 %arg) { 654; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 655; CHECK-LABEL: define {{[^@]+}}@phi 656; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { 657; CHECK-NEXT: bb: 658; CHECK-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5 659; CHECK-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]] 660; CHECK: bb1: 661; CHECK-NEXT: br label [[BB3:%.*]] 662; CHECK: bb2: 663; CHECK-NEXT: br label [[BB3]] 664; CHECK: bb3: 665; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10 666; CHECK-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]] 667; CHECK: bb5: 668; CHECK-NEXT: br label [[BB9:%.*]] 669; CHECK: bb7: 670; CHECK-NEXT: br label [[BB9]] 671; CHECK: bb9: 672; CHECK-NEXT: br label [[BB12:%.*]] 673; CHECK: bb11: 674; CHECK-NEXT: unreachable 675; CHECK: bb12: 676; CHECK-NEXT: br label [[BB13:%.*]] 677; CHECK: bb13: 678; CHECK-NEXT: ret i1 false 679; 680bb: 681 %tmp = icmp sgt i32 %arg, 5 682 br i1 %tmp, label %bb1, label %bb2 683 684bb1: ; preds = %bb 685 br label %bb3 686 687bb2: ; preds = %bb 688 br label %bb3 689 690bb3: ; preds = %bb2, %bb1 691 %.02 = phi i32 [ 1, %bb1 ], [ 2, %bb2 ] 692 %tmp4 = icmp sgt i32 %arg, 10 693 br i1 %tmp4, label %bb5, label %bb7 694 695bb5: ; preds = %bb3 696 %tmp6 = add nsw i32 %.02, 1 697 br label %bb9 698 699bb7: ; preds = %bb3 700 %tmp8 = add nsw i32 %.02, 2 701 br label %bb9 702 703bb9: ; preds = %bb7, %bb5 704 %.01 = phi i32 [ %tmp6, %bb5 ], [ %tmp8, %bb7 ] 705 %tmp10 = icmp eq i32 %.01, 5 706 br i1 %tmp10, label %bb11, label %bb12 707 708bb11: ; preds = %bb9 709 br label %bb13 710 711bb12: ; preds = %bb9 712 br label %bb13 713 714bb13: ; preds = %bb12, %bb11 715 %.0 = phi i1 [ true, %bb11 ], [ false, %bb12 ] 716 ret i1 %.0 717} 718 719define dso_local i1 @select(i32 %a) local_unnamed_addr #0 { 720; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 721; CHECK-LABEL: define {{[^@]+}}@select 722; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { 723; CHECK-NEXT: entry: 724; CHECK-NEXT: ret i1 false 725; 726entry: 727 %cmp = icmp sgt i32 %a, 5 728 %. = select i1 %cmp, i32 1, i32 2 729 %cmp1 = icmp sgt i32 %a, 10 730 %y.0.v = select i1 %cmp1, i32 1, i32 2 731 %y.0 = add nuw nsw i32 %., %y.0.v 732 %cmp6 = icmp eq i32 %y.0, 5 733 ret i1 %cmp6 734} 735 736define dso_local i32 @select_zext(i32 %a) local_unnamed_addr #0 { 737; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 738; CHECK-LABEL: define {{[^@]+}}@select_zext 739; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { 740; CHECK-NEXT: entry: 741; CHECK-NEXT: ret i32 0 742; 743entry: 744 %cmp = icmp sgt i32 %a, 5 745 %. = select i1 %cmp, i32 1, i32 2 746 %cmp1 = icmp sgt i32 %a, 10 747 %y.0.v = select i1 %cmp1, i32 1, i32 2 748 %y.0 = add nuw nsw i32 %., %y.0.v 749 %cmp6 = icmp eq i32 %y.0, 5 750 %.13 = zext i1 %cmp6 to i32 751 ret i32 %.13 752} 753 754define dso_local i64 @select_int2ptr_bitcast_ptr2int(i32 %a) local_unnamed_addr #0 { 755; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 756; CHECK-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int 757; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { 758; CHECK-NEXT: entry: 759; CHECK-NEXT: ret i64 0 760; 761entry: 762 %cmp = icmp sgt i32 %a, 5 763 %. = select i1 %cmp, i32 1, i32 2 764 %cmp1 = icmp sgt i32 %a, 10 765 %y.0.v = select i1 %cmp1, i32 1, i32 2 766 %y.0 = add nuw nsw i32 %., %y.0.v 767 %cmp6 = icmp eq i32 %y.0, 5 768 %i2p = inttoptr i1 %cmp6 to i1* 769 %bc = bitcast i1* %i2p to i32* 770 %p2i = ptrtoint i32* %bc to i64 771 ret i64 %p2i 772} 773 774; } 775 776define i1 @f_fcmp(float %a, float %b) { 777; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 778; CHECK-LABEL: define {{[^@]+}}@f_fcmp 779; CHECK-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR1]] { 780; CHECK-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]] 781; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false 782; CHECK-NEXT: ret i1 [[S]] 783; 784 %r = fcmp uge float %a, %b 785 %s = select i1 %r, i1 %r, i1 0 786 ret i1 %s 787} 788define i1 @d_fcmp(double %a, double %b) { 789; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 790; CHECK-LABEL: define {{[^@]+}}@d_fcmp 791; CHECK-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR1]] { 792; CHECK-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]] 793; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false 794; CHECK-NEXT: ret i1 [[S]] 795; 796 %r = fcmp oeq double %a, %b 797 %s = select i1 %r, i1 %r, i1 0 798 ret i1 %s 799} 800define i1 @dp_icmp(double* %a, double* %b) { 801; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 802; CHECK-LABEL: define {{[^@]+}}@dp_icmp 803; CHECK-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]]) #[[ATTR1]] { 804; CHECK-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]] 805; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false 806; CHECK-NEXT: ret i1 [[S]] 807; 808 %r = icmp sge double* %a, %b 809 %s = select i1 %r, i1 %r, i1 0 810 ret i1 %s 811} 812define i1 @ip_icmp(i8* %a, i8* %b) { 813; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 814; CHECK-LABEL: define {{[^@]+}}@ip_icmp 815; CHECK-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]]) #[[ATTR1]] { 816; CHECK-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]] 817; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false 818; CHECK-NEXT: ret i1 [[S]] 819; 820 %r = icmp ult i8* %a, %b 821 %s = select i1 %r, i1 %r, i1 0 822 ret i1 %s 823} 824define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, double* %dpa, double* %dpb, i8* %ipa, i8* %ipb) { 825; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 826; IS________OPM-LABEL: define {{[^@]+}}@fcmp_caller 827; IS________OPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) #[[ATTR1]] { 828; IS________OPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR5]] 829; IS________OPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR5]] 830; IS________OPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR5]] 831; IS________OPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR5]] 832; IS________OPM-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]] 833; IS________OPM-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]] 834; IS________OPM-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]] 835; IS________OPM-NEXT: ret i1 [[O3]] 836; 837; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 838; IS________NPM-LABEL: define {{[^@]+}}@fcmp_caller 839; IS________NPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) #[[ATTR1]] { 840; IS________NPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR4]] 841; IS________NPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR4]] 842; IS________NPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR4]] 843; IS________NPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR4]] 844; IS________NPM-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]] 845; IS________NPM-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]] 846; IS________NPM-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]] 847; IS________NPM-NEXT: ret i1 [[O3]] 848; 849 %r1 = call i1 @f_fcmp(float %fa, float %fb) 850 %r2 = call i1 @d_fcmp(double %da, double %db) 851 %r3 = call i1 @dp_icmp(double* %dpa, double* %dpb) 852 %r4 = call i1 @ip_icmp(i8* %ipa, i8* %ipb) 853 %o1 = or i1 %r1, %r2 854 %o2 = or i1 %r3, %r4 855 %o3 = or i1 %o1, %o2 856 ret i1 %o3 857} 858 859define i8 @ret_two() { 860; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 861; CHECK-LABEL: define {{[^@]+}}@ret_two 862; CHECK-SAME: () #[[ATTR1]] { 863; CHECK-NEXT: ret i8 2 864; 865 ret i8 2 866} 867define i8 @ret_undef() { 868; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 869; CHECK-LABEL: define {{[^@]+}}@ret_undef 870; CHECK-SAME: () #[[ATTR1]] { 871; CHECK-NEXT: ret i8 undef 872; 873 ret i8 undef 874} 875 876; Verify we collapse undef to a value and return something non-undef here. 877define i8 @undef_collapse_1() { 878; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 879; CHECK-LABEL: define {{[^@]+}}@undef_collapse_1 880; CHECK-SAME: () #[[ATTR1]] { 881; CHECK-NEXT: ret i8 0 882; 883 %c = call i8 @ret_undef() 884 %s = shl i8 %c, 2 885 ret i8 %s 886} 887 888; Verify we collapse undef to a value and return something non-undef here. 889define i8 @undef_collapse_2() { 890; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 891; CHECK-LABEL: define {{[^@]+}}@undef_collapse_2 892; CHECK-SAME: () #[[ATTR1]] { 893; CHECK-NEXT: ret i8 0 894; 895 %c = call i8 @ret_two() 896 %s = shl i8 undef, %c 897 ret i8 %s 898} 899 900define i8 @undef_collapse_caller() { 901; 902; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 903; CHECK-LABEL: define {{[^@]+}}@undef_collapse_caller 904; CHECK-SAME: () #[[ATTR1]] { 905; CHECK-NEXT: ret i8 0 906; 907 %c1 = call i8 @undef_collapse_1() 908 %c2 = call i8 @undef_collapse_2() 909 %a = add i8 %c1, %c2 910 ret i8 %a 911} 912 913define i32 @ret1or2(i1 %c) { 914; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 915; CHECK-LABEL: define {{[^@]+}}@ret1or2 916; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { 917; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2 918; CHECK-NEXT: ret i32 [[S]] 919; 920 %s = select i1 %c, i32 1, i32 2 921 ret i32 %s 922} 923define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) { 924; 925; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 926; CHECK-LABEL: define {{[^@]+}}@callee_range_1 927; CHECK-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR1]] { 928; CHECK-NEXT: ret i1 true 929; 930 %r1 = call i32 @ret1or2(i1 %c1) 931 %r2 = call i32 @ret1or2(i1 %c2) 932 %indirection = select i1 %c3, i32 %r1, i32 %r2 933 %a = add i32 %r1, %indirection 934 %i1 = icmp sle i32 %a, 4 935 %i2 = icmp sge i32 %a, 2 936 %f = and i1 %i1, %i2 937 ret i1 %f 938} 939 940define i1 @callee_range_2(i1 %c1, i1 %c2) { 941; 942; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 943; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callee_range_2 944; IS__TUNIT_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] { 945; IS__TUNIT_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR5]], !range [[RNG4:![0-9]+]] 946; IS__TUNIT_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR5]], !range [[RNG4]] 947; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] 948; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 949; IS__TUNIT_OPM-NEXT: ret i1 [[I1]] 950; 951; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 952; IS________NPM-LABEL: define {{[^@]+}}@callee_range_2 953; IS________NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] { 954; IS________NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]], !range [[RNG5:![0-9]+]] 955; IS________NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]], !range [[RNG5]] 956; IS________NPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] 957; IS________NPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 958; IS________NPM-NEXT: ret i1 [[I1]] 959; 960; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 961; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callee_range_2 962; IS__CGSCC_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] { 963; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR5]], !range [[RNG5:![0-9]+]] 964; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR5]], !range [[RNG5]] 965; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] 966; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 967; IS__CGSCC_OPM-NEXT: ret i1 [[I1]] 968; 969 %r1 = call i32 @ret1or2(i1 %c1) 970 %r2 = call i32 @ret1or2(i1 %c2) 971 %a = add i32 %r1, %r2 972 %i1 = icmp sle i32 %a, 3 973 %i2 = icmp sge i32 %a, 2 974 %f = and i1 %i1, %i2 975 ret i1 %f 976} 977 978 979define i32 @ret100() { 980; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 981; CHECK-LABEL: define {{[^@]+}}@ret100 982; CHECK-SAME: () #[[ATTR1]] { 983; CHECK-NEXT: ret i32 100 984; 985 ret i32 100 986} 987 988define i1 @ctx_adjustment(i32 %V) { 989; 990; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 991; IS________OPM-LABEL: define {{[^@]+}}@ctx_adjustment 992; IS________OPM-SAME: (i32 [[V:%.*]]) #[[ATTR1]] { 993; IS________OPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100 994; IS________OPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 995; IS________OPM: if.true: 996; IS________OPM-NEXT: br label [[END:%.*]] 997; IS________OPM: if.false: 998; IS________OPM-NEXT: br label [[END]] 999; IS________OPM: end: 1000; IS________OPM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ] 1001; IS________OPM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100 1002; IS________OPM-NEXT: ret i1 [[C2]] 1003; 1004; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1005; IS________NPM-LABEL: define {{[^@]+}}@ctx_adjustment 1006; IS________NPM-SAME: (i32 [[V:%.*]]) #[[ATTR1]] { 1007; IS________NPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100 1008; IS________NPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 1009; IS________NPM: if.true: 1010; IS________NPM-NEXT: br label [[END:%.*]] 1011; IS________NPM: if.false: 1012; IS________NPM-NEXT: br label [[END]] 1013; IS________NPM: end: 1014; IS________NPM-NEXT: ret i1 true 1015; 1016 %c1 = icmp sge i32 %V, 100 1017 br i1 %c1, label %if.true, label %if.false 1018if.true: 1019 br label %end 1020if.false: 1021 %call = call i32 @ret100() 1022 br label %end 1023end: 1024 %phi = phi i32 [ %V, %if.true ], [ %call, %if.false ] 1025 %c2 = icmp sge i32 %phi, 100 1026 ret i1 %c2 1027} 1028 1029 1030define i32 @func(i1 %c) { 1031; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1032; CHECK-LABEL: define {{[^@]+}}@func 1033; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { 1034; CHECK-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1 1035; CHECK-NEXT: ret i32 [[RET]] 1036; 1037 %ret = select i1 %c, i32 0, i32 1 1038 ret i32 %ret 1039} 1040 1041define i32 @simplify_callsite_argument(i1 %d) { 1042; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1043; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@simplify_callsite_argument 1044; IS__TUNIT_OPM-SAME: (i1 [[D:%.*]]) #[[ATTR1]] { 1045; IS__TUNIT_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false 1046; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 1047; IS__TUNIT_OPM: t: 1048; IS__TUNIT_OPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR5]], !range [[RNG3]] 1049; IS__TUNIT_OPM-NEXT: ret i32 [[RET1]] 1050; IS__TUNIT_OPM: f: 1051; IS__TUNIT_OPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR5]], !range [[RNG3]] 1052; IS__TUNIT_OPM-NEXT: ret i32 [[RET2]] 1053; 1054; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1055; IS________NPM-LABEL: define {{[^@]+}}@simplify_callsite_argument 1056; IS________NPM-SAME: (i1 [[D:%.*]]) #[[ATTR1]] { 1057; IS________NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false 1058; IS________NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 1059; IS________NPM: t: 1060; IS________NPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef true) #[[ATTR4]], !range [[RNG4]] 1061; IS________NPM-NEXT: ret i32 [[RET1]] 1062; IS________NPM: f: 1063; IS________NPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR4]], !range [[RNG4]] 1064; IS________NPM-NEXT: ret i32 [[RET2]] 1065; 1066; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1067; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@simplify_callsite_argument 1068; IS__CGSCC_OPM-SAME: (i1 [[D:%.*]]) #[[ATTR1]] { 1069; IS__CGSCC_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false 1070; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 1071; IS__CGSCC_OPM: t: 1072; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR5]], !range [[RNG4]] 1073; IS__CGSCC_OPM-NEXT: ret i32 [[RET1]] 1074; IS__CGSCC_OPM: f: 1075; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR5]], !range [[RNG4]] 1076; IS__CGSCC_OPM-NEXT: ret i32 [[RET2]] 1077; 1078 %c = select i1 %d, i1 true, i1 false 1079 br i1 %c, label %t, label %f 1080t: 1081 %ret1 = call i32 @func(i1 %c) 1082 ret i32 %ret1 1083f: 1084 %ret2 = call i32 @func(i1 false) 1085 ret i32 %ret2 1086} 1087 1088define internal i32 @less_than_65536(i32 %arg) { 1089; 1090; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1091; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_65536 1092; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { 1093; IS__CGSCC____-NEXT: [[SHRINKED:%.*]] = udiv i32 [[ARG]], 65536 1094; IS__CGSCC____-NEXT: ret i32 [[SHRINKED]] 1095; 1096 %shrinked = udiv i32 %arg, 65536 1097 ret i32 %shrinked 1098} 1099 1100define internal i1 @is_less_than_65536(i32 %arg) { 1101; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1102; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_65536 1103; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { 1104; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp ult i32 [[ARG]], 65536 1105; IS__CGSCC____-NEXT: ret i1 [[CMP]] 1106; 1107 %cmp = icmp ult i32 %arg, 65536 1108 ret i1 %cmp 1109} 1110 1111define i1 @check_divided_range(i32 %arg) { 1112; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1113; CHECK-LABEL: define {{[^@]+}}@check_divided_range 1114; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { 1115; CHECK-NEXT: ret i1 true 1116; 1117 %csret1 = call i32 @less_than_65536(i32 0) 1118 %csret2 = call i32 @less_than_65536(i32 %arg) 1119 %true1 = call i1 @is_less_than_65536(i32 %csret1) 1120 %true2 = call i1 @is_less_than_65536(i32 %csret2) 1121 %ret = and i1 %true1, %true2 1122 ret i1 %ret 1123} 1124 1125define internal i32 @cast_and_return(i1 %c) { 1126; 1127; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1128; IS__CGSCC____-LABEL: define {{[^@]+}}@cast_and_return 1129; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { 1130; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[C]] to i32 1131; IS__CGSCC____-NEXT: ret i32 [[RET]] 1132; 1133 %ret = zext i1 %c to i32 1134 ret i32 %ret 1135} 1136 1137define internal i1 @is_less_than_3(i32 %c) { 1138; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1139; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_3 1140; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { 1141; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 3 1142; IS__CGSCC____-NEXT: ret i1 [[CMP]] 1143; 1144 %cmp = icmp slt i32 %c, 3 1145 ret i1 %cmp 1146} 1147 1148define i1 @check_casted_range(i1 %c) { 1149; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1150; CHECK-LABEL: define {{[^@]+}}@check_casted_range 1151; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { 1152; CHECK-NEXT: ret i1 true 1153; 1154 %csret1 = call i32 @cast_and_return(i1 true) 1155 %csret2 = call i32 @cast_and_return(i1 %c) 1156 %add = add i32 %csret1, %csret2 1157 %ret = call i1 @is_less_than_3(i32 %add) 1158 ret i1 %ret 1159} 1160 1161define internal i32 @less_than_100_1(i32 %c) { 1162; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1163; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_100_1 1164; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { 1165; IS__CGSCC____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ 1166; IS__CGSCC____-NEXT: i32 0, label [[ONZERO:%.*]] 1167; IS__CGSCC____-NEXT: i32 1, label [[ONONE:%.*]] 1168; IS__CGSCC____-NEXT: i32 2, label [[ONTWO:%.*]] 1169; IS__CGSCC____-NEXT: i32 3, label [[ONTHREE:%.*]] 1170; IS__CGSCC____-NEXT: i32 4, label [[ONFOUR:%.*]] 1171; IS__CGSCC____-NEXT: i32 5, label [[ONFIVE:%.*]] 1172; IS__CGSCC____-NEXT: i32 6, label [[ONSIX:%.*]] 1173; IS__CGSCC____-NEXT: ] 1174; IS__CGSCC____: onzero: 1175; IS__CGSCC____-NEXT: ret i32 0 1176; IS__CGSCC____: onone: 1177; IS__CGSCC____-NEXT: ret i32 1 1178; IS__CGSCC____: ontwo: 1179; IS__CGSCC____-NEXT: ret i32 2 1180; IS__CGSCC____: onthree: 1181; IS__CGSCC____-NEXT: ret i32 3 1182; IS__CGSCC____: onfour: 1183; IS__CGSCC____-NEXT: ret i32 4 1184; IS__CGSCC____: onfive: 1185; IS__CGSCC____-NEXT: ret i32 5 1186; IS__CGSCC____: onsix: 1187; IS__CGSCC____-NEXT: ret i32 6 1188; IS__CGSCC____: otherwise: 1189; IS__CGSCC____-NEXT: ret i32 99 1190; 1191 switch i32 %c, label %otherwise [ i32 0, label %onzero 1192 i32 1, label %onone 1193 i32 2, label %ontwo 1194 i32 3, label %onthree 1195 i32 4, label %onfour 1196 i32 5, label %onfive 1197 i32 6, label %onsix] 1198onzero: 1199 ret i32 0 1200onone: 1201 ret i32 1 1202ontwo: 1203 ret i32 2 1204onthree: 1205 ret i32 3 1206onfour: 1207 ret i32 4 1208onfive: 1209 ret i32 5 1210onsix: 1211 ret i32 6 1212otherwise: 1213 ret i32 99 1214} 1215 1216define internal i1 @is_less_than_100_1(i32 %c) { 1217; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1218; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_100_1 1219; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { 1220; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 1221; IS__CGSCC____-NEXT: ret i1 [[CMP]] 1222; 1223 %cmp = icmp slt i32 %c, 100 1224 ret i1 %cmp 1225} 1226 1227define i1 @propagate_range1(i32 %c){ 1228; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1229; CHECK-LABEL: define {{[^@]+}}@propagate_range1 1230; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { 1231; CHECK-NEXT: ret i1 true 1232; 1233 %csret = call i32 @less_than_100_1(i32 %c) 1234 %true = call i1 @is_less_than_100_1(i32 %csret) 1235 ret i1 %true 1236} 1237 1238define internal i32 @less_than_100_2(i32 %c) { 1239; 1240; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1241; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_100_2 1242; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { 1243; IS__CGSCC____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ 1244; IS__CGSCC____-NEXT: i32 0, label [[ONZERO:%.*]] 1245; IS__CGSCC____-NEXT: i32 1, label [[ONONE:%.*]] 1246; IS__CGSCC____-NEXT: i32 2, label [[ONTWO:%.*]] 1247; IS__CGSCC____-NEXT: i32 3, label [[ONTHREE:%.*]] 1248; IS__CGSCC____-NEXT: i32 4, label [[ONFOUR:%.*]] 1249; IS__CGSCC____-NEXT: i32 5, label [[ONFIVE:%.*]] 1250; IS__CGSCC____-NEXT: i32 6, label [[ONSIX:%.*]] 1251; IS__CGSCC____-NEXT: ] 1252; IS__CGSCC____: onzero: 1253; IS__CGSCC____-NEXT: ret i32 0 1254; IS__CGSCC____: onone: 1255; IS__CGSCC____-NEXT: ret i32 1 1256; IS__CGSCC____: ontwo: 1257; IS__CGSCC____-NEXT: ret i32 2 1258; IS__CGSCC____: onthree: 1259; IS__CGSCC____-NEXT: ret i32 3 1260; IS__CGSCC____: onfour: 1261; IS__CGSCC____-NEXT: ret i32 4 1262; IS__CGSCC____: onfive: 1263; IS__CGSCC____-NEXT: ret i32 5 1264; IS__CGSCC____: onsix: 1265; IS__CGSCC____-NEXT: ret i32 6 1266; IS__CGSCC____: otherwise: 1267; IS__CGSCC____-NEXT: ret i32 99 1268; 1269 switch i32 %c, label %otherwise [ i32 0, label %onzero 1270 i32 1, label %onone 1271 i32 2, label %ontwo 1272 i32 3, label %onthree 1273 i32 4, label %onfour 1274 i32 5, label %onfive 1275 i32 6, label %onsix] 1276onzero: 1277 ret i32 0 1278onone: 1279 ret i32 1 1280ontwo: 1281 ret i32 2 1282onthree: 1283 ret i32 3 1284onfour: 1285 ret i32 4 1286onfive: 1287 ret i32 5 1288onsix: 1289 ret i32 6 1290otherwise: 1291 ret i32 99 1292} 1293 1294define internal i1 @is_less_than_100_2(i32 %c) { 1295; 1296; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1297; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_100_2 1298; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { 1299; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 1300; IS__CGSCC____-NEXT: ret i1 [[CMP]] 1301; 1302 %cmp = icmp slt i32 %c, 100 1303 ret i1 %cmp 1304} 1305 1306define i1 @propagate_range2(i32 %c) { 1307; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1308; CHECK-LABEL: define {{[^@]+}}@propagate_range2 1309; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { 1310; CHECK-NEXT: ret i1 true 1311; 1312 %csret1 = call i32 @less_than_100_2(i32 0) 1313 %true1 = call i1 @is_less_than_100_2(i32 %csret1) 1314 %csret2 = call i32 @less_than_100_2(i32 %c) 1315 %true2 = call i1 @is_less_than_100_2(i32 %csret2) 1316 %true = and i1 %true1, %true2 1317 ret i1 %true 1318} 1319 1320define internal i1 @non_zero(i8 %v) { 1321; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1322; IS________OPM-LABEL: define {{[^@]+}}@non_zero 1323; IS________OPM-SAME: (i8 [[V:%.*]]) #[[ATTR1]] { 1324; IS________OPM-NEXT: [[R:%.*]] = icmp ne i8 [[V]], 0 1325; IS________OPM-NEXT: ret i1 [[R]] 1326; 1327; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1328; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@non_zero 1329; IS__CGSCC_NPM-SAME: () #[[ATTR1]] { 1330; IS__CGSCC_NPM-NEXT: ret i1 true 1331; 1332 %r = icmp ne i8 %v, 0 1333 ret i1 %r 1334} 1335 1336; Avoid range metadata for %l below 1337define i1 @context(i8* %p) { 1338; IS________OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 1339; IS________OPM-LABEL: define {{[^@]+}}@context 1340; IS________OPM-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR0]] { 1341; IS________OPM-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 1342; IS________OPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]] 1343; IS________OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 1344; IS________OPM: t: 1345; IS________OPM-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR5]] 1346; IS________OPM-NEXT: ret i1 [[R]] 1347; IS________OPM: f: 1348; IS________OPM-NEXT: ret i1 false 1349; 1350; IS________NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 1351; IS________NPM-LABEL: define {{[^@]+}}@context 1352; IS________NPM-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR0]] { 1353; IS________NPM-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 1354; IS________NPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]] 1355; IS________NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 1356; IS________NPM: t: 1357; IS________NPM-NEXT: ret i1 true 1358; IS________NPM: f: 1359; IS________NPM-NEXT: ret i1 false 1360; 1361 %l = load i8, i8* %p 1362 %c = icmp slt i8 0, %l 1363 br i1 %c, label %t, label %f 1364t: 1365 %r = call i1 @non_zero(i8 %l) 1366 ret i1 %r 1367f: 1368 ret i1 false 1369} 1370 1371 1372define void @spam(i32* %arg, i32* %arg1) { 1373; CHECK-LABEL: define {{[^@]+}}@spam 1374; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[ARG:%.*]], i32* nocapture nofree readnone [[ARG1:%.*]]) { 1375; CHECK-NEXT: bb: 1376; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[ARG]], align 8 1377; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP]], 4 1378; CHECK-NEXT: br i1 [[TMP2]], label [[BB3:%.*]], label [[BB4:%.*]] 1379; CHECK: bb3: 1380; CHECK-NEXT: call fastcc void @wobble(i32 signext [[TMP]]) 1381; CHECK-NEXT: br label [[BB5:%.*]] 1382; CHECK: bb4: 1383; CHECK-NEXT: call void @ham(i32 [[TMP]]) 1384; CHECK-NEXT: br label [[BB5]] 1385; CHECK: bb5: 1386; CHECK-NEXT: ret void 1387; 1388bb: 1389 %tmp = load i32, i32* %arg, align 8 1390 %tmp2 = icmp ult i32 %tmp, 4 1391 br i1 %tmp2, label %bb3, label %bb4 1392 1393bb3: ; preds = %bb 1394 call fastcc void @wobble(i32 signext %tmp) 1395 br label %bb5 1396 1397bb4: ; preds = %bb 1398 call void @ham(i32 %tmp) 1399 br label %bb5 1400 1401bb5: ; preds = %bb4, %bb3 1402 ret void 1403} 1404 1405define internal fastcc void @wobble(i32 signext %arg) { 1406; CHECK-LABEL: define {{[^@]+}}@wobble 1407; CHECK-SAME: (i32 signext [[ARG:%.*]]) { 1408; CHECK-NEXT: bb: 1409; CHECK-NEXT: [[TMP:%.*]] = icmp ult i32 [[ARG]], 2 1410; CHECK-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]] 1411; CHECK: bb1: 1412; CHECK-NEXT: call void @barney(i32 noundef signext 32, i32 noundef signext 0) 1413; CHECK-NEXT: br label [[BB3:%.*]] 1414; CHECK: bb2: 1415; CHECK-NEXT: br label [[BB3]] 1416; CHECK: bb3: 1417; CHECK-NEXT: ret void 1418; 1419bb: 1420 %tmp = icmp ult i32 %arg, 2 1421 br i1 %tmp, label %bb1, label %bb2 1422 1423bb1: ; preds = %bb 1424 call void @barney(i32 signext 32, i32 signext 0) 1425 br label %bb3 1426 1427bb2: ; preds = %bb 1428 br label %bb3 1429 1430bb3: ; preds = %bb2, %bb1 1431 ret void 1432} 1433 1434define i1 @loop_1(i32 %N) { 1435; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone 1436; CHECK-LABEL: define {{[^@]+}}@loop_1 1437; CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR2:[0-9]+]] { 1438; CHECK-NEXT: entry: 1439; CHECK-NEXT: br label [[HEADER:%.*]] 1440; CHECK: header: 1441; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[AND:%.*]], [[HEADER]] ] 1442; CHECK-NEXT: [[INC:%.*]] = add i32 [[I]], 1 1443; CHECK-NEXT: [[AND]] = and i32 [[INC]], 9999 1444; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[N]], [[AND]] 1445; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] 1446; CHECK: exit: 1447; CHECK-NEXT: [[R:%.*]] = icmp sle i32 [[I]], 5 1448; CHECK-NEXT: ret i1 [[R]] 1449; 1450entry: 1451 br label %header 1452header: 1453 %i = phi i32 [0, %entry], [%and, %header] 1454 %inc = add i32 %i, 1 1455 %and = and i32 %inc, 9999 1456 %cmp = icmp ne i32 %N, %and 1457 br i1 %cmp, label %header, label %exit 1458exit: 1459 %r = icmp sle i32 %i, 5 1460 ret i1 %r 1461} 1462 1463declare void @ham(i32) 1464 1465declare void @barney(i32 signext, i32 signext) 1466 1467 1468!0 = !{i32 0, i32 10} 1469!1 = !{i32 10, i32 100} 1470;. 1471; IS__TUNIT_OPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } 1472; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } 1473; IS__TUNIT_OPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone } 1474; IS__TUNIT_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind readonly willreturn } 1475; IS__TUNIT_OPM: attributes #[[ATTR4]] = { nofree nosync nounwind readnone } 1476; IS__TUNIT_OPM: attributes #[[ATTR5]] = { nofree nosync nounwind readnone willreturn } 1477;. 1478; IS__TUNIT_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } 1479; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } 1480; IS__TUNIT_NPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone } 1481; IS__TUNIT_NPM: attributes #[[ATTR3]] = { nofree nosync nounwind readonly willreturn } 1482; IS__TUNIT_NPM: attributes #[[ATTR4]] = { nofree nosync nounwind readnone willreturn } 1483;. 1484; IS__CGSCC_OPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } 1485; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } 1486; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone } 1487; IS__CGSCC_OPM: attributes #[[ATTR3]] = { readonly willreturn } 1488; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nounwind readnone } 1489; IS__CGSCC_OPM: attributes #[[ATTR5]] = { readnone willreturn } 1490;. 1491; IS__CGSCC_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } 1492; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } 1493; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone } 1494; IS__CGSCC_NPM: attributes #[[ATTR3]] = { readonly willreturn } 1495; IS__CGSCC_NPM: attributes #[[ATTR4]] = { readnone willreturn } 1496;. 1497; IS__TUNIT_OPM: [[RNG0]] = !{i32 0, i32 10} 1498; IS__TUNIT_OPM: [[RNG1]] = !{i32 10, i32 100} 1499; IS__TUNIT_OPM: [[RNG2]] = !{i32 200, i32 1091} 1500; IS__TUNIT_OPM: [[RNG3]] = !{i32 0, i32 2} 1501; IS__TUNIT_OPM: [[RNG4]] = !{i32 1, i32 3} 1502;. 1503; IS________NPM: [[RNG0]] = !{i32 0, i32 10} 1504; IS________NPM: [[RNG1]] = !{i32 10, i32 100} 1505; IS________NPM: [[RNG2]] = !{i32 200, i32 1091} 1506; IS________NPM: [[RNG3]] = !{i32 1, i32 -2147483648} 1507; IS________NPM: [[RNG4]] = !{i32 0, i32 2} 1508; IS________NPM: [[RNG5]] = !{i32 1, i32 3} 1509;. 1510; IS__CGSCC_OPM: [[RNG0]] = !{i32 0, i32 10} 1511; IS__CGSCC_OPM: [[RNG1]] = !{i32 10, i32 100} 1512; IS__CGSCC_OPM: [[RNG2]] = !{i32 200, i32 1091} 1513; IS__CGSCC_OPM: [[RNG3]] = !{i32 10, i32 21} 1514; IS__CGSCC_OPM: [[RNG4]] = !{i32 0, i32 2} 1515; IS__CGSCC_OPM: [[RNG5]] = !{i32 1, i32 3} 1516;. 1517