1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instsimplify,verify -S | FileCheck %s 3 4define i1 @ule_null_constexpr(ptr %x) { 5; CHECK-LABEL: @ule_null_constexpr( 6; CHECK-NEXT: ret i1 true 7; 8 %cmp = icmp ule ptr null, @ule_null_constexpr 9 ret i1 %cmp 10} 11 12define i1 @ugt_null_constexpr(ptr %x) { 13; CHECK-LABEL: @ugt_null_constexpr( 14; CHECK-NEXT: ret i1 false 15; 16 %cmp = icmp ugt ptr null, @ugt_null_constexpr 17 ret i1 %cmp 18} 19 20define i1 @uge_constexpr_null(ptr %x) { 21; CHECK-LABEL: @uge_constexpr_null( 22; CHECK-NEXT: ret i1 true 23; 24 %cmp = icmp uge ptr @ugt_null_constexpr, null 25 ret i1 %cmp 26} 27 28define i1 @ult_constexpr_null(ptr %x) { 29; CHECK-LABEL: @ult_constexpr_null( 30; CHECK-NEXT: ret i1 false 31; 32 %cmp = icmp ult ptr @ugt_null_constexpr, null 33 ret i1 %cmp 34} 35 36; Negative test - we don't know if the constexpr is null. 37 38define i1 @ule_constexpr_null(ptr %x) { 39; CHECK-LABEL: @ule_constexpr_null( 40; CHECK-NEXT: ret i1 false 41; 42 %cmp = icmp ule ptr @ugt_null_constexpr, null 43 ret i1 %cmp 44} 45 46; Negative test - we don't know if the constexpr is *signed* less-than null. 47 48define i1 @slt_constexpr_null(ptr %x) { 49; CHECK-LABEL: @slt_constexpr_null( 50; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr @ugt_null_constexpr, null 51; CHECK-NEXT: ret i1 [[CMP]] 52; 53 %cmp = icmp slt ptr @ugt_null_constexpr, null 54 ret i1 %cmp 55} 56 57; Negative test - we don't try to evaluate this comparison of constant expressions. 58 59define i1 @ult_constexpr_constexpr_one(ptr %x) { 60; CHECK-LABEL: @ult_constexpr_constexpr_one( 61; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr @ugt_null_constexpr, inttoptr (i32 1 to ptr) 62; CHECK-NEXT: ret i1 [[CMP]] 63; 64 %cmp = icmp ult ptr @ugt_null_constexpr, inttoptr (i32 1 to ptr) 65 ret i1 %cmp 66} 67 68@g = global [2 x i32] [i32 1, i32 2] 69@g2 = global i32 0 70@g2_weak = extern_weak global i32 71@g3 = global i8 0 72 73define i1 @global_ne_null() { 74; CHECK-LABEL: @global_ne_null( 75; CHECK-NEXT: ret i1 true 76; 77 %cmp = icmp ne ptr @g, null 78 ret i1 %cmp 79} 80 81define i1 @global_ugt_null() { 82; CHECK-LABEL: @global_ugt_null( 83; CHECK-NEXT: ret i1 true 84; 85 %cmp = icmp ugt ptr @g, null 86 ret i1 %cmp 87} 88 89define i1 @global_sgt_null() { 90; CHECK-LABEL: @global_sgt_null( 91; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr @g, null 92; CHECK-NEXT: ret i1 [[CMP]] 93; 94 %cmp = icmp sgt ptr @g, null 95 ret i1 %cmp 96} 97 98; Should not fold to true, as the gep computes a null value. 99define i1 @global_out_of_bounds_gep_ne_null() { 100; CHECK-LABEL: @global_out_of_bounds_gep_ne_null( 101; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr getelementptr (i8, ptr @g3, i64 sub (i64 0, i64 ptrtoint (ptr @g3 to i64))), null 102; CHECK-NEXT: ret i1 [[CMP]] 103; 104 %cmp = icmp ne ptr getelementptr (i8, ptr @g3, i64 sub (i64 0, i64 ptrtoint (ptr @g3 to i64))), null 105 ret i1 %cmp 106} 107 108define i1 @global_inbounds_gep_ne_null() { 109; CHECK-LABEL: @global_inbounds_gep_ne_null( 110; CHECK-NEXT: ret i1 true 111; 112 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1 113 %cmp = icmp ne ptr %gep, null 114 ret i1 %cmp 115} 116 117define i1 @global_gep_ugt_null() { 118; CHECK-LABEL: @global_gep_ugt_null( 119; CHECK-NEXT: ret i1 true 120; 121 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1 122 %cmp = icmp ugt ptr %gep, null 123 ret i1 %cmp 124} 125 126define i1 @global_gep_sgt_null() { 127; CHECK-LABEL: @global_gep_sgt_null( 128; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr getelementptr inbounds nuw (i8, ptr @g, i64 8), null 129; CHECK-NEXT: ret i1 [[CMP]] 130; 131 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1 132 %cmp = icmp sgt ptr %gep, null 133 ret i1 %cmp 134} 135 136; @g2_weak may be null, in which case this is a zero-index GEP and the pointers 137; are equal. 138define i1 @null_gep_ne_null() { 139; CHECK-LABEL: @null_gep_ne_null( 140; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), null 141; CHECK-NEXT: ret i1 [[CMP]] 142; 143 %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64) 144 %cmp = icmp ne ptr %gep, null 145 ret i1 %cmp 146} 147 148define i1 @null_gep_ugt_null() { 149; CHECK-LABEL: @null_gep_ugt_null( 150; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), null 151; CHECK-NEXT: ret i1 [[CMP]] 152; 153 %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64) 154 %cmp = icmp ugt ptr %gep, null 155 ret i1 %cmp 156} 157 158define i1 @null_gep_sgt_null() { 159; CHECK-LABEL: @null_gep_sgt_null( 160; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), null 161; CHECK-NEXT: ret i1 [[CMP]] 162; 163 %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64) 164 %cmp = icmp sgt ptr %gep, null 165 ret i1 %cmp 166} 167 168define i1 @null_gep_ne_null_constant_int() { 169; CHECK-LABEL: @null_gep_ne_null_constant_int( 170; CHECK-NEXT: ret i1 true 171; 172 %gep = getelementptr i8, ptr null, i64 1 173 %cmp = icmp ne ptr %gep, null 174 ret i1 %cmp 175} 176 177define i1 @null_gep_ugt_null_constant_int() { 178; CHECK-LABEL: @null_gep_ugt_null_constant_int( 179; CHECK-NEXT: ret i1 true 180; 181 %gep = getelementptr i8, ptr null, i64 1 182 %cmp = icmp ugt ptr %gep, null 183 ret i1 %cmp 184} 185 186define i1 @null_gep_ne_global() { 187; CHECK-LABEL: @null_gep_ne_global( 188; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g3 to i64)), @g3 189; CHECK-NEXT: ret i1 [[CMP]] 190; 191 %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g3 to i64) 192 %cmp = icmp ne ptr %gep, @g3 193 ret i1 %cmp 194} 195 196define i1 @null_gep_ult_global() { 197; CHECK-LABEL: @null_gep_ult_global( 198; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g3 to i64)), @g3 199; CHECK-NEXT: ret i1 [[CMP]] 200; 201 %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g3 to i64) 202 %cmp = icmp ult ptr %gep, @g3 203 ret i1 %cmp 204} 205 206define i1 @null_gep_slt_global() { 207; CHECK-LABEL: @null_gep_slt_global( 208; CHECK-NEXT: [[CMP:%.*]] = icmp slt ptr getelementptr ([2 x i32], ptr null, i64 ptrtoint (ptr @g2 to i64)), @g 209; CHECK-NEXT: ret i1 [[CMP]] 210; 211 %gep = getelementptr [2 x i32], ptr null, i64 ptrtoint (ptr @g2 to i64) 212 %cmp = icmp slt ptr %gep, @g 213 ret i1 %cmp 214} 215 216define i1 @global_gep_ne_global() { 217; CHECK-LABEL: @global_gep_ne_global( 218; CHECK-NEXT: ret i1 true 219; 220 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1 221 %cmp = icmp ne ptr %gep, @g 222 ret i1 %cmp 223} 224 225define i1 @global_gep_ugt_global() { 226; CHECK-LABEL: @global_gep_ugt_global( 227; CHECK-NEXT: ret i1 true 228; 229 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1 230 %cmp = icmp ugt ptr %gep, @g 231 ret i1 %cmp 232} 233 234define i1 @global_gep_sgt_global() { 235; CHECK-LABEL: @global_gep_sgt_global( 236; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr getelementptr inbounds nuw (i8, ptr @g, i64 8), @g 237; CHECK-NEXT: ret i1 [[CMP]] 238; 239 %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1 240 %cmp = icmp sgt ptr %gep, @g 241 ret i1 %cmp 242} 243 244; This should not fold to true, as the offset is negative. 245define i1 @global_gep_ugt_global_neg_offset() { 246; CHECK-LABEL: @global_gep_ugt_global_neg_offset( 247; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr getelementptr (i8, ptr @g, i64 -8), @g 248; CHECK-NEXT: ret i1 [[CMP]] 249; 250 %gep = getelementptr [2 x i32], ptr @g, i64 -1 251 %cmp = icmp ugt ptr %gep, @g 252 ret i1 %cmp 253} 254 255define i1 @global_gep_sgt_global_neg_offset() { 256; CHECK-LABEL: @global_gep_sgt_global_neg_offset( 257; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr getelementptr (i8, ptr @g, i64 -8), @g 258; CHECK-NEXT: ret i1 [[CMP]] 259; 260 %gep = getelementptr [2 x i32], ptr @g, i64 -1 261 %cmp = icmp sgt ptr %gep, @g 262 ret i1 %cmp 263} 264 265define i1 @global_gep_ugt_global_gep() { 266; CHECK-LABEL: @global_gep_ugt_global_gep( 267; CHECK-NEXT: ret i1 true 268; 269 %gep2 = getelementptr inbounds [2 x i32], ptr @g, i64 0, i64 1 270 %cmp = icmp ugt ptr %gep2, @g 271 ret i1 %cmp 272} 273 274; Should not fold due to signed comparison. 275define i1 @global_gep_sgt_global_gep() { 276; CHECK-LABEL: @global_gep_sgt_global_gep( 277; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr getelementptr inbounds nuw (i8, ptr @g, i64 4), @g 278; CHECK-NEXT: ret i1 [[CMP]] 279; 280 %gep2 = getelementptr inbounds [2 x i32], ptr @g, i64 0, i64 1 281 %cmp = icmp sgt ptr %gep2, @g 282 ret i1 %cmp 283} 284 285define i1 @global_gep_ugt_global_gep_complex() { 286; CHECK-LABEL: @global_gep_ugt_global_gep_complex( 287; CHECK-NEXT: ret i1 true 288; 289 %gep3 = getelementptr inbounds i8, ptr @g, i64 2 290 %cmp = icmp ugt ptr %gep3, @g 291 ret i1 %cmp 292} 293 294declare void @func() 295 296define i1 @global_no_cfi() { 297; CHECK-LABEL: @global_no_cfi( 298; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr @func, no_cfi @func 299; CHECK-NEXT: ret i1 [[CMP]] 300; 301 %cmp = icmp eq ptr @func, no_cfi @func 302 ret i1 %cmp 303} 304 305define i1 @blockaddr_no_cfi() { 306; CHECK-LABEL: @blockaddr_no_cfi( 307; CHECK-NEXT: br label [[BB:%.*]] 308; CHECK: bb: 309; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr blockaddress(@blockaddr_no_cfi, [[BB]]), no_cfi @func 310; CHECK-NEXT: ret i1 [[CMP]] 311; 312 br label %bb 313 314bb: 315 %cmp = icmp eq ptr blockaddress(@blockaddr_no_cfi, %bb), no_cfi @func 316 ret i1 %cmp 317} 318 319define i1 @global_no_cfi_dso_local_equivalent() { 320; CHECK-LABEL: @global_no_cfi_dso_local_equivalent( 321; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr dso_local_equivalent @func, no_cfi @func 322; CHECK-NEXT: ret i1 [[CMP]] 323; 324 %cmp = icmp eq ptr dso_local_equivalent @func, no_cfi @func 325 ret i1 %cmp 326} 327