149d6e3ebSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 249d6e3ebSFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 349d6e3ebSFlorian Hahn 4c5e1ddb6SFlorian Hahndefine i32 @test.ult(ptr readonly %src, ptr readnone %min, ptr readnone %max) { 549d6e3ebSFlorian Hahn; CHECK-LABEL: @test.ult( 649d6e3ebSFlorian Hahn; CHECK-NEXT: check.0.min: 7c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult ptr [[SRC:%.*]], [[MIN:%.*]] 849d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_MIN_0]], label [[TRAP:%.*]], label [[CHECK_0_MAX:%.*]] 949d6e3ebSFlorian Hahn; CHECK: trap: 1049d6e3ebSFlorian Hahn; CHECK-NEXT: ret i32 10 1149d6e3ebSFlorian Hahn; CHECK: check.0.max: 12c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_MAX_0:%.*]] = icmp ult ptr [[SRC]], [[MAX:%.*]] 1349d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_MAX_0]], label [[CHECK_3_MIN:%.*]], label [[TRAP]] 1449d6e3ebSFlorian Hahn; CHECK: check.3.min: 15c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[L0:%.*]] = load i32, ptr [[SRC]], align 4 16c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I36:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 3 1749d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 false, label [[TRAP]], label [[CHECK_3_MAX:%.*]] 1849d6e3ebSFlorian Hahn; CHECK: check.3.max: 19c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I36]], [[MAX]] 2049d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_3_MAX]], label [[CHECK_1_MIN:%.*]], label [[TRAP]] 2149d6e3ebSFlorian Hahn; CHECK: check.1.min: 22c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[ADD_PTR_I36]], align 4 23c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I29:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 1 2449d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 false, label [[TRAP]], label [[CHECK_1_MAX:%.*]] 2549d6e3ebSFlorian Hahn; CHECK: check.1.max: 2649d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 true, label [[CHECK_2_MIN:%.*]], label [[TRAP]] 2749d6e3ebSFlorian Hahn; CHECK: check.2.min: 28c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[ADD_PTR_I29]], align 4 29c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 2 3049d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 false, label [[TRAP]], label [[CHECK_2_MAX:%.*]] 3149d6e3ebSFlorian Hahn; CHECK: check.2.max: 3249d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[TRAP]] 3349d6e3ebSFlorian Hahn; CHECK: exit: 34c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4 3549d6e3ebSFlorian Hahn; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[L1]], [[L0]] 3649d6e3ebSFlorian Hahn; CHECK-NEXT: [[ADD8:%.*]] = add nsw i32 [[ADD]], [[L2]] 3749d6e3ebSFlorian Hahn; CHECK-NEXT: [[ADD9:%.*]] = add nsw i32 [[ADD8]], [[L3]] 3849d6e3ebSFlorian Hahn; CHECK-NEXT: ret i32 [[ADD9]] 3949d6e3ebSFlorian Hahn; 4049d6e3ebSFlorian Hahncheck.0.min: 41c5e1ddb6SFlorian Hahn %c.min.0 = icmp ult ptr %src, %min 4249d6e3ebSFlorian Hahn br i1 %c.min.0, label %trap, label %check.0.max 4349d6e3ebSFlorian Hahn 44c5e1ddb6SFlorian Hahntrap: 4549d6e3ebSFlorian Hahn ret i32 10 4649d6e3ebSFlorian Hahn 47c5e1ddb6SFlorian Hahncheck.0.max: 48c5e1ddb6SFlorian Hahn %c.max.0 = icmp ult ptr %src, %max 4949d6e3ebSFlorian Hahn br i1 %c.max.0, label %check.3.min, label %trap 5049d6e3ebSFlorian Hahn 51c5e1ddb6SFlorian Hahncheck.3.min: 52c5e1ddb6SFlorian Hahn %l0 = load i32, ptr %src, align 4 53c5e1ddb6SFlorian Hahn %add.ptr.i36 = getelementptr inbounds i32, ptr %src, i64 3 54c5e1ddb6SFlorian Hahn %c.3.min = icmp ult ptr %add.ptr.i36, %min 5549d6e3ebSFlorian Hahn br i1 %c.3.min, label %trap, label %check.3.max 5649d6e3ebSFlorian Hahn 57c5e1ddb6SFlorian Hahncheck.3.max: 58c5e1ddb6SFlorian Hahn %c.3.max = icmp ult ptr %add.ptr.i36, %max 5949d6e3ebSFlorian Hahn br i1 %c.3.max, label %check.1.min, label %trap 6049d6e3ebSFlorian Hahn 61c5e1ddb6SFlorian Hahncheck.1.min: 62c5e1ddb6SFlorian Hahn %l1 = load i32, ptr %add.ptr.i36, align 4 63c5e1ddb6SFlorian Hahn %add.ptr.i29 = getelementptr inbounds i32, ptr %src, i64 1 64c5e1ddb6SFlorian Hahn %c.1.min = icmp ult ptr %add.ptr.i29, %min 6549d6e3ebSFlorian Hahn br i1 %c.1.min, label %trap, label %check.1.max 6649d6e3ebSFlorian Hahn 67c5e1ddb6SFlorian Hahncheck.1.max: 68c5e1ddb6SFlorian Hahn %c.1.max = icmp ult ptr %add.ptr.i29, %max 6949d6e3ebSFlorian Hahn br i1 %c.1.max, label %check.2.min, label %trap 7049d6e3ebSFlorian Hahn 71c5e1ddb6SFlorian Hahncheck.2.min: 72c5e1ddb6SFlorian Hahn %l2 = load i32, ptr %add.ptr.i29, align 4 73c5e1ddb6SFlorian Hahn %add.ptr.i = getelementptr inbounds i32, ptr %src, i64 2 74c5e1ddb6SFlorian Hahn %c.2.min = icmp ult ptr %add.ptr.i, %min 7549d6e3ebSFlorian Hahn br i1 %c.2.min, label %trap, label %check.2.max 7649d6e3ebSFlorian Hahn 77c5e1ddb6SFlorian Hahncheck.2.max: 78c5e1ddb6SFlorian Hahn %c.2.max = icmp ult ptr %add.ptr.i, %max 7949d6e3ebSFlorian Hahn br i1 %c.2.max, label %exit, label %trap 8049d6e3ebSFlorian Hahn 81c5e1ddb6SFlorian Hahnexit: 82c5e1ddb6SFlorian Hahn %l3 = load i32, ptr %add.ptr.i, align 4 8349d6e3ebSFlorian Hahn %add = add nsw i32 %l1, %l0 8449d6e3ebSFlorian Hahn %add8 = add nsw i32 %add, %l2 8549d6e3ebSFlorian Hahn %add9 = add nsw i32 %add8, %l3 8649d6e3ebSFlorian Hahn ret i32 %add9 8749d6e3ebSFlorian Hahn} 8849d6e3ebSFlorian Hahn 8949d6e3ebSFlorian Hahn; Same as test.ult, but without inbounds. 90c5e1ddb6SFlorian Hahndefine i32 @test.ult_no_inbounds(ptr readonly %src, ptr readnone %min, ptr readnone %max) { 9149d6e3ebSFlorian Hahn; CHECK-LABEL: @test.ult_no_inbounds( 9249d6e3ebSFlorian Hahn; CHECK-NEXT: check.0.min: 93c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult ptr [[SRC:%.*]], [[MIN:%.*]] 9449d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_MIN_0]], label [[TRAP:%.*]], label [[CHECK_0_MAX:%.*]] 9549d6e3ebSFlorian Hahn; CHECK: trap: 9649d6e3ebSFlorian Hahn; CHECK-NEXT: ret i32 10 9749d6e3ebSFlorian Hahn; CHECK: check.0.max: 98c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_MAX_0:%.*]] = icmp ult ptr [[SRC]], [[MAX:%.*]] 9949d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_MAX_0]], label [[CHECK_3_MIN:%.*]], label [[TRAP]] 10049d6e3ebSFlorian Hahn; CHECK: check.3.min: 101c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[L0:%.*]] = load i32, ptr [[SRC]], align 4 102c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I36:%.*]] = getelementptr i32, ptr [[SRC]], i64 3 103c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult ptr [[ADD_PTR_I36]], [[MIN]] 10449d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_3_MIN]], label [[TRAP]], label [[CHECK_3_MAX:%.*]] 10549d6e3ebSFlorian Hahn; CHECK: check.3.max: 106c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I36]], [[MAX]] 10749d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_3_MAX]], label [[CHECK_1_MIN:%.*]], label [[TRAP]] 10849d6e3ebSFlorian Hahn; CHECK: check.1.min: 109c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[ADD_PTR_I36]], align 4 110c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I29:%.*]] = getelementptr i32, ptr [[SRC]], i64 1 111c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult ptr [[ADD_PTR_I29]], [[MIN]] 11249d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_1_MIN]], label [[TRAP]], label [[CHECK_1_MAX:%.*]] 11349d6e3ebSFlorian Hahn; CHECK: check.1.max: 114c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I29]], [[MAX]] 11549d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_1_MAX]], label [[CHECK_2_MIN:%.*]], label [[TRAP]] 11649d6e3ebSFlorian Hahn; CHECK: check.2.min: 117c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[ADD_PTR_I29]], align 4 118c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr i32, ptr [[SRC]], i64 2 119c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult ptr [[ADD_PTR_I]], [[MIN]] 12049d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_2_MIN]], label [[TRAP]], label [[CHECK_2_MAX:%.*]] 12149d6e3ebSFlorian Hahn; CHECK: check.2.max: 122c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult ptr [[ADD_PTR_I]], [[MAX]] 12349d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_2_MAX]], label [[EXIT:%.*]], label [[TRAP]] 12449d6e3ebSFlorian Hahn; CHECK: exit: 125c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4 12649d6e3ebSFlorian Hahn; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[L1]], [[L0]] 12749d6e3ebSFlorian Hahn; CHECK-NEXT: [[ADD8:%.*]] = add nsw i32 [[ADD]], [[L2]] 12849d6e3ebSFlorian Hahn; CHECK-NEXT: [[ADD9:%.*]] = add nsw i32 [[ADD8]], [[L3]] 12949d6e3ebSFlorian Hahn; CHECK-NEXT: ret i32 [[ADD9]] 13049d6e3ebSFlorian Hahn; 13149d6e3ebSFlorian Hahncheck.0.min: 132c5e1ddb6SFlorian Hahn %c.min.0 = icmp ult ptr %src, %min 13349d6e3ebSFlorian Hahn br i1 %c.min.0, label %trap, label %check.0.max 13449d6e3ebSFlorian Hahn 135c5e1ddb6SFlorian Hahntrap: 13649d6e3ebSFlorian Hahn ret i32 10 13749d6e3ebSFlorian Hahn 138c5e1ddb6SFlorian Hahncheck.0.max: 139c5e1ddb6SFlorian Hahn %c.max.0 = icmp ult ptr %src, %max 14049d6e3ebSFlorian Hahn br i1 %c.max.0, label %check.3.min, label %trap 14149d6e3ebSFlorian Hahn 142c5e1ddb6SFlorian Hahncheck.3.min: 143c5e1ddb6SFlorian Hahn %l0 = load i32, ptr %src, align 4 144c5e1ddb6SFlorian Hahn %add.ptr.i36 = getelementptr i32, ptr %src, i64 3 145c5e1ddb6SFlorian Hahn %c.3.min = icmp ult ptr %add.ptr.i36, %min 14649d6e3ebSFlorian Hahn br i1 %c.3.min, label %trap, label %check.3.max 14749d6e3ebSFlorian Hahn 148c5e1ddb6SFlorian Hahncheck.3.max: 149c5e1ddb6SFlorian Hahn %c.3.max = icmp ult ptr %add.ptr.i36, %max 15049d6e3ebSFlorian Hahn br i1 %c.3.max, label %check.1.min, label %trap 15149d6e3ebSFlorian Hahn 152c5e1ddb6SFlorian Hahncheck.1.min: 153c5e1ddb6SFlorian Hahn %l1 = load i32, ptr %add.ptr.i36, align 4 154c5e1ddb6SFlorian Hahn %add.ptr.i29 = getelementptr i32, ptr %src, i64 1 155c5e1ddb6SFlorian Hahn %c.1.min = icmp ult ptr %add.ptr.i29, %min 15649d6e3ebSFlorian Hahn br i1 %c.1.min, label %trap, label %check.1.max 15749d6e3ebSFlorian Hahn 158c5e1ddb6SFlorian Hahncheck.1.max: 159c5e1ddb6SFlorian Hahn %c.1.max = icmp ult ptr %add.ptr.i29, %max 16049d6e3ebSFlorian Hahn br i1 %c.1.max, label %check.2.min, label %trap 16149d6e3ebSFlorian Hahn 162c5e1ddb6SFlorian Hahncheck.2.min: 163c5e1ddb6SFlorian Hahn %l2 = load i32, ptr %add.ptr.i29, align 4 164c5e1ddb6SFlorian Hahn %add.ptr.i = getelementptr i32, ptr %src, i64 2 165c5e1ddb6SFlorian Hahn %c.2.min = icmp ult ptr %add.ptr.i, %min 16649d6e3ebSFlorian Hahn br i1 %c.2.min, label %trap, label %check.2.max 16749d6e3ebSFlorian Hahn 168c5e1ddb6SFlorian Hahncheck.2.max: 169c5e1ddb6SFlorian Hahn %c.2.max = icmp ult ptr %add.ptr.i, %max 17049d6e3ebSFlorian Hahn br i1 %c.2.max, label %exit, label %trap 17149d6e3ebSFlorian Hahn 172c5e1ddb6SFlorian Hahnexit: 173c5e1ddb6SFlorian Hahn %l3 = load i32, ptr %add.ptr.i, align 4 17449d6e3ebSFlorian Hahn %add = add nsw i32 %l1, %l0 17549d6e3ebSFlorian Hahn %add8 = add nsw i32 %add, %l2 17649d6e3ebSFlorian Hahn %add9 = add nsw i32 %add8, %l3 17749d6e3ebSFlorian Hahn ret i32 %add9 17849d6e3ebSFlorian Hahn} 17949d6e3ebSFlorian Hahn 180c5e1ddb6SFlorian Hahndefine void @test.not.uge.ult(ptr %start, ptr %low, ptr %high) { 18149d6e3ebSFlorian Hahn; CHECK-LABEL: @test.not.uge.ult( 18249d6e3ebSFlorian Hahn; CHECK-NEXT: entry: 183c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3 184c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]] 18549d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 18649d6e3ebSFlorian Hahn; CHECK: if.then: 18749d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 18849d6e3ebSFlorian Hahn; CHECK: if.end: 18949d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 true) 190c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1 19149d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 true) 192c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2 19349d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 true) 194c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3 19549d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 true) 196c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4 197c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_4:%.*]] = icmp ult ptr [[START_4]], [[HIGH]] 19849d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_4]]) 19949d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 20049d6e3ebSFlorian Hahn; 20149d6e3ebSFlorian Hahnentry: 202c5e1ddb6SFlorian Hahn %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3 203c5e1ddb6SFlorian Hahn %c.1 = icmp uge ptr %add.ptr.i, %high 20449d6e3ebSFlorian Hahn br i1 %c.1, label %if.then, label %if.end 20549d6e3ebSFlorian Hahn 206c5e1ddb6SFlorian Hahnif.then: 20749d6e3ebSFlorian Hahn ret void 20849d6e3ebSFlorian Hahn 209c5e1ddb6SFlorian Hahnif.end: 210c5e1ddb6SFlorian Hahn %t.0 = icmp ult ptr %start, %high 21149d6e3ebSFlorian Hahn call void @use(i1 %t.0) 212c5e1ddb6SFlorian Hahn %start.1 = getelementptr inbounds i8, ptr %start, i64 1 213c5e1ddb6SFlorian Hahn %t.1 = icmp ult ptr %start.1, %high 21449d6e3ebSFlorian Hahn call void @use(i1 %t.1) 215c5e1ddb6SFlorian Hahn %start.2 = getelementptr inbounds i8, ptr %start, i64 2 216c5e1ddb6SFlorian Hahn %t.2 = icmp ult ptr %start.2, %high 21749d6e3ebSFlorian Hahn call void @use(i1 %t.2) 218c5e1ddb6SFlorian Hahn %start.3 = getelementptr inbounds i8, ptr %start, i64 3 219c5e1ddb6SFlorian Hahn %t.3 = icmp ult ptr %start.3, %high 22049d6e3ebSFlorian Hahn call void @use(i1 %t.3) 221c5e1ddb6SFlorian Hahn %start.4 = getelementptr inbounds i8, ptr %start, i64 4 222c5e1ddb6SFlorian Hahn %c.4 = icmp ult ptr %start.4, %high 22349d6e3ebSFlorian Hahn call void @use(i1 %c.4) 22449d6e3ebSFlorian Hahn ret void 22549d6e3ebSFlorian Hahn} 22649d6e3ebSFlorian Hahn 22749d6e3ebSFlorian Hahn; Same as test.not.uge.ult, but without inbounds GEPs. 228c5e1ddb6SFlorian Hahndefine void @test.not.uge.ult_no_inbounds(ptr %start, ptr %low, ptr %high) { 22949d6e3ebSFlorian Hahn; CHECK-LABEL: @test.not.uge.ult_no_inbounds( 23049d6e3ebSFlorian Hahn; CHECK-NEXT: entry: 231c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr i8, ptr [[START:%.*]], i64 3 232c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]] 23349d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 23449d6e3ebSFlorian Hahn; CHECK: if.then: 23549d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 23649d6e3ebSFlorian Hahn; CHECK: if.end: 237c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[T_0:%.*]] = icmp ult ptr [[START]], [[HIGH]] 23849d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[T_0]]) 239c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_1:%.*]] = getelementptr i8, ptr [[START]], i64 1 240c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp ult ptr [[START_1]], [[HIGH]] 24149d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[T_1]]) 242c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_2:%.*]] = getelementptr i8, ptr [[START]], i64 2 243c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[START_2]], [[HIGH]] 24449d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[T_2]]) 245c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_3:%.*]] = getelementptr i8, ptr [[START]], i64 3 246c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[T_3:%.*]] = icmp ult ptr [[START_3]], [[HIGH]] 24749d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[T_3]]) 248c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_4:%.*]] = getelementptr i8, ptr [[START]], i64 4 249c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_4:%.*]] = icmp ult ptr [[START_4]], [[HIGH]] 25049d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_4]]) 25149d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 25249d6e3ebSFlorian Hahn; 25349d6e3ebSFlorian Hahnentry: 254c5e1ddb6SFlorian Hahn %add.ptr.i = getelementptr i8, ptr %start, i64 3 255c5e1ddb6SFlorian Hahn %c.1 = icmp uge ptr %add.ptr.i, %high 25649d6e3ebSFlorian Hahn br i1 %c.1, label %if.then, label %if.end 25749d6e3ebSFlorian Hahn 258c5e1ddb6SFlorian Hahnif.then: 25949d6e3ebSFlorian Hahn ret void 26049d6e3ebSFlorian Hahn 261c5e1ddb6SFlorian Hahnif.end: 262c5e1ddb6SFlorian Hahn %t.0 = icmp ult ptr %start, %high 26349d6e3ebSFlorian Hahn call void @use(i1 %t.0) 264c5e1ddb6SFlorian Hahn %start.1 = getelementptr i8, ptr %start, i64 1 265c5e1ddb6SFlorian Hahn %t.1 = icmp ult ptr %start.1, %high 26649d6e3ebSFlorian Hahn call void @use(i1 %t.1) 267c5e1ddb6SFlorian Hahn %start.2 = getelementptr i8, ptr %start, i64 2 268c5e1ddb6SFlorian Hahn %t.2 = icmp ult ptr %start.2, %high 26949d6e3ebSFlorian Hahn call void @use(i1 %t.2) 270c5e1ddb6SFlorian Hahn %start.3 = getelementptr i8, ptr %start, i64 3 271c5e1ddb6SFlorian Hahn %t.3 = icmp ult ptr %start.3, %high 27249d6e3ebSFlorian Hahn call void @use(i1 %t.3) 273c5e1ddb6SFlorian Hahn %start.4 = getelementptr i8, ptr %start, i64 4 274c5e1ddb6SFlorian Hahn %c.4 = icmp ult ptr %start.4, %high 27549d6e3ebSFlorian Hahn call void @use(i1 %c.4) 27649d6e3ebSFlorian Hahn ret void 27749d6e3ebSFlorian Hahn} 27849d6e3ebSFlorian Hahn 279c5e1ddb6SFlorian Hahndefine void @test.not.uge.ule(ptr %start, ptr %low, ptr %high) { 28049d6e3ebSFlorian Hahn; CHECK-LABEL: @test.not.uge.ule( 28149d6e3ebSFlorian Hahn; CHECK-NEXT: entry: 282c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3 283c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]] 28449d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 28549d6e3ebSFlorian Hahn; CHECK: if.then: 28649d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 28749d6e3ebSFlorian Hahn; CHECK: if.end: 28849d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 true) 289c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1 29049d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 true) 291c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2 29249d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 true) 293c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3 29449d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 true) 295c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4 29649d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 true) 297c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5 298c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_5:%.*]] = icmp ule ptr [[START_5]], [[HIGH]] 29949d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_5]]) 30049d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 30149d6e3ebSFlorian Hahn; 30249d6e3ebSFlorian Hahnentry: 303c5e1ddb6SFlorian Hahn %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3 304c5e1ddb6SFlorian Hahn %c.1 = icmp uge ptr %add.ptr.i, %high 30549d6e3ebSFlorian Hahn br i1 %c.1, label %if.then, label %if.end 30649d6e3ebSFlorian Hahn 307c5e1ddb6SFlorian Hahnif.then: 30849d6e3ebSFlorian Hahn ret void 30949d6e3ebSFlorian Hahn 310c5e1ddb6SFlorian Hahnif.end: 311c5e1ddb6SFlorian Hahn %t.0 = icmp ule ptr %start, %high 31249d6e3ebSFlorian Hahn call void @use(i1 %t.0) 313c5e1ddb6SFlorian Hahn %start.1 = getelementptr inbounds i8, ptr %start, i64 1 314c5e1ddb6SFlorian Hahn %t.1 = icmp ule ptr %start.1, %high 31549d6e3ebSFlorian Hahn call void @use(i1 %t.1) 316c5e1ddb6SFlorian Hahn %start.2 = getelementptr inbounds i8, ptr %start, i64 2 317c5e1ddb6SFlorian Hahn %t.2 = icmp ule ptr %start.2, %high 31849d6e3ebSFlorian Hahn call void @use(i1 %t.2) 319c5e1ddb6SFlorian Hahn %start.3 = getelementptr inbounds i8, ptr %start, i64 3 320c5e1ddb6SFlorian Hahn %t.3 = icmp ule ptr %start.3, %high 32149d6e3ebSFlorian Hahn call void @use(i1 %t.3) 322c5e1ddb6SFlorian Hahn %start.4 = getelementptr inbounds i8, ptr %start, i64 4 323c5e1ddb6SFlorian Hahn %t.4 = icmp ule ptr %start.4, %high 32449d6e3ebSFlorian Hahn call void @use(i1 %t.4) 325c5e1ddb6SFlorian Hahn %start.5 = getelementptr inbounds i8, ptr %start, i64 5 326c5e1ddb6SFlorian Hahn %c.5 = icmp ule ptr %start.5, %high 32749d6e3ebSFlorian Hahn call void @use(i1 %c.5) 32849d6e3ebSFlorian Hahn ret void 32949d6e3ebSFlorian Hahn} 33049d6e3ebSFlorian Hahn 331c5e1ddb6SFlorian Hahndefine void @test.not.uge.ugt(ptr %start, ptr %low, ptr %high) { 33249d6e3ebSFlorian Hahn; CHECK-LABEL: @test.not.uge.ugt( 33349d6e3ebSFlorian Hahn; CHECK-NEXT: entry: 334c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3 335c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]] 33649d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 33749d6e3ebSFlorian Hahn; CHECK: if.then: 33849d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 33949d6e3ebSFlorian Hahn; CHECK: if.end: 34049d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 false) 341c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1 34249d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 false) 343c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2 34449d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 false) 345c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3 34649d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 false) 347c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4 34849d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 false) 349c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5 350c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_5:%.*]] = icmp ugt ptr [[START_5]], [[HIGH]] 35149d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_5]]) 35249d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 35349d6e3ebSFlorian Hahn; 35449d6e3ebSFlorian Hahnentry: 355c5e1ddb6SFlorian Hahn %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3 356c5e1ddb6SFlorian Hahn %c.1 = icmp uge ptr %add.ptr.i, %high 35749d6e3ebSFlorian Hahn br i1 %c.1, label %if.then, label %if.end 35849d6e3ebSFlorian Hahn 359c5e1ddb6SFlorian Hahnif.then: 36049d6e3ebSFlorian Hahn ret void 36149d6e3ebSFlorian Hahn 362c5e1ddb6SFlorian Hahnif.end: 363c5e1ddb6SFlorian Hahn %f.0 = icmp ugt ptr %start, %high 36449d6e3ebSFlorian Hahn call void @use(i1 %f.0) 365c5e1ddb6SFlorian Hahn %start.1 = getelementptr inbounds i8, ptr %start, i64 1 366c5e1ddb6SFlorian Hahn %f.1 = icmp ugt ptr %start.1, %high 36749d6e3ebSFlorian Hahn call void @use(i1 %f.1) 368c5e1ddb6SFlorian Hahn %start.2 = getelementptr inbounds i8, ptr %start, i64 2 369c5e1ddb6SFlorian Hahn %f.2 = icmp ugt ptr %start.2, %high 37049d6e3ebSFlorian Hahn call void @use(i1 %f.2) 371c5e1ddb6SFlorian Hahn %start.3 = getelementptr inbounds i8, ptr %start, i64 3 372c5e1ddb6SFlorian Hahn %f.3 = icmp ugt ptr %start.3, %high 37349d6e3ebSFlorian Hahn call void @use(i1 %f.3) 374c5e1ddb6SFlorian Hahn %start.4 = getelementptr inbounds i8, ptr %start, i64 4 375c5e1ddb6SFlorian Hahn %f.4 = icmp ugt ptr %start.4, %high 37649d6e3ebSFlorian Hahn call void @use(i1 %f.4) 377c5e1ddb6SFlorian Hahn %start.5 = getelementptr inbounds i8, ptr %start, i64 5 378c5e1ddb6SFlorian Hahn %c.5 = icmp ugt ptr %start.5, %high 37949d6e3ebSFlorian Hahn call void @use(i1 %c.5) 38049d6e3ebSFlorian Hahn ret void 38149d6e3ebSFlorian Hahn} 38249d6e3ebSFlorian Hahn 383c5e1ddb6SFlorian Hahndefine void @test.not.uge.uge(ptr %start, ptr %low, ptr %high) { 38449d6e3ebSFlorian Hahn; CHECK-LABEL: @test.not.uge.uge( 38549d6e3ebSFlorian Hahn; CHECK-NEXT: entry: 386c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i64 3 387c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]] 38849d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 38949d6e3ebSFlorian Hahn; CHECK: if.then: 39049d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 39149d6e3ebSFlorian Hahn; CHECK: if.end: 39249d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 false) 393c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1 39449d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 false) 395c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 2 39649d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 false) 397c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_3:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 3 39849d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 false) 399c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_4:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 4 400c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_4:%.*]] = icmp uge ptr [[START_4]], [[HIGH]] 40149d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_4]]) 402c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_5:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 5 403c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_5:%.*]] = icmp uge ptr [[START_5]], [[HIGH]] 40449d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_5]]) 40549d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 40649d6e3ebSFlorian Hahn; 40749d6e3ebSFlorian Hahnentry: 408c5e1ddb6SFlorian Hahn %add.ptr.i = getelementptr inbounds i8, ptr %start, i64 3 409c5e1ddb6SFlorian Hahn %c.1 = icmp uge ptr %add.ptr.i, %high 41049d6e3ebSFlorian Hahn br i1 %c.1, label %if.then, label %if.end 41149d6e3ebSFlorian Hahn 412c5e1ddb6SFlorian Hahnif.then: 41349d6e3ebSFlorian Hahn ret void 41449d6e3ebSFlorian Hahn 415c5e1ddb6SFlorian Hahnif.end: 416c5e1ddb6SFlorian Hahn %f.0 = icmp ugt ptr %start, %high 41749d6e3ebSFlorian Hahn call void @use(i1 %f.0) 418c5e1ddb6SFlorian Hahn %start.1 = getelementptr inbounds i8, ptr %start, i64 1 419c5e1ddb6SFlorian Hahn %f.1 = icmp uge ptr %start.1, %high 42049d6e3ebSFlorian Hahn call void @use(i1 %f.1) 421c5e1ddb6SFlorian Hahn %start.2 = getelementptr inbounds i8, ptr %start, i64 2 422c5e1ddb6SFlorian Hahn %f.2 = icmp uge ptr %start.2, %high 42349d6e3ebSFlorian Hahn call void @use(i1 %f.2) 424c5e1ddb6SFlorian Hahn %start.3 = getelementptr inbounds i8, ptr %start, i64 3 425c5e1ddb6SFlorian Hahn %f.3 = icmp uge ptr %start.3, %high 42649d6e3ebSFlorian Hahn call void @use(i1 %f.3) 427c5e1ddb6SFlorian Hahn %start.4 = getelementptr inbounds i8, ptr %start, i64 4 428c5e1ddb6SFlorian Hahn %c.4 = icmp uge ptr %start.4, %high 42949d6e3ebSFlorian Hahn call void @use(i1 %c.4) 430c5e1ddb6SFlorian Hahn %start.5 = getelementptr inbounds i8, ptr %start, i64 5 431c5e1ddb6SFlorian Hahn %c.5 = icmp uge ptr %start.5, %high 43249d6e3ebSFlorian Hahn call void @use(i1 %c.5) 43349d6e3ebSFlorian Hahn ret void 43449d6e3ebSFlorian Hahn} 43549d6e3ebSFlorian Hahn 436c5e1ddb6SFlorian Hahndefine void @test.not.uge.uge.nonconst(ptr %start, ptr %low, ptr %high, i8 %off) { 43749d6e3ebSFlorian Hahn; CHECK-LABEL: @test.not.uge.uge.nonconst( 43849d6e3ebSFlorian Hahn; CHECK-NEXT: entry: 439c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i8 [[OFF:%.*]] 440c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp uge ptr [[ADD_PTR_I]], [[HIGH:%.*]] 44149d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 44249d6e3ebSFlorian Hahn; CHECK: if.then: 443c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_OFF_2:%.*]] = getelementptr inbounds i8, ptr [[START]], i8 [[OFF]] 444c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[T_0:%.*]] = icmp uge ptr [[START_OFF_2]], [[HIGH]] 44506f3ef66SFlorian Hahn; CHECK-NEXT: call void @use(i1 [[T_0]]) 44649d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 44749d6e3ebSFlorian Hahn; CHECK: if.end: 448c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_1:%.*]] = getelementptr inbounds i8, ptr [[START]], i64 1 449c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_0:%.*]] = icmp uge ptr [[START_1]], [[HIGH]] 45049d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_0]]) 451c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[START_OFF:%.*]] = getelementptr inbounds i8, ptr [[START]], i8 [[OFF]] 452c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[F_0:%.*]] = icmp uge ptr [[START_OFF]], [[HIGH]] 45306f3ef66SFlorian Hahn; CHECK-NEXT: call void @use(i1 [[F_0]]) 45449d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 45549d6e3ebSFlorian Hahn; 45649d6e3ebSFlorian Hahnentry: 457c5e1ddb6SFlorian Hahn %add.ptr.i = getelementptr inbounds i8, ptr %start, i8 %off 458c5e1ddb6SFlorian Hahn %c.1 = icmp uge ptr %add.ptr.i, %high 45949d6e3ebSFlorian Hahn br i1 %c.1, label %if.then, label %if.end 46049d6e3ebSFlorian Hahn 461c5e1ddb6SFlorian Hahnif.then: 462c5e1ddb6SFlorian Hahn %start.off.2 = getelementptr inbounds i8, ptr %start, i8 %off 463c5e1ddb6SFlorian Hahn %t.0 = icmp uge ptr %start.off.2, %high 46449d6e3ebSFlorian Hahn call void @use(i1 %t.0) 46549d6e3ebSFlorian Hahn ret void 46649d6e3ebSFlorian Hahn 467c5e1ddb6SFlorian Hahnif.end: 468c5e1ddb6SFlorian Hahn %start.1 = getelementptr inbounds i8, ptr %start, i64 1 469c5e1ddb6SFlorian Hahn %c.0 = icmp uge ptr %start.1, %high 47049d6e3ebSFlorian Hahn call void @use(i1 %c.0) 471c5e1ddb6SFlorian Hahn %start.off = getelementptr inbounds i8, ptr %start, i8 %off 472c5e1ddb6SFlorian Hahn %f.0 = icmp uge ptr %start.off, %high 47349d6e3ebSFlorian Hahn call void @use(i1 %f.0) 47449d6e3ebSFlorian Hahn ret void 47549d6e3ebSFlorian Hahn} 47649d6e3ebSFlorian Hahn 47749d6e3ebSFlorian Hahn; Test which requires decomposing GEP %ptr, SHL(). 478c5e1ddb6SFlorian Hahndefine void @test.ult.gep.shl(ptr readonly %src, ptr readnone %max, i8 %idx) { 47949d6e3ebSFlorian Hahn; CHECK-LABEL: @test.ult.gep.shl( 48049d6e3ebSFlorian Hahn; CHECK-NEXT: check.0.min: 481c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_10:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i32 10 482c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_ADD_10_MAX:%.*]] = icmp ugt ptr [[ADD_10]], [[MAX:%.*]] 48349d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]] 48449d6e3ebSFlorian Hahn; CHECK: trap: 48549d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 48649d6e3ebSFlorian Hahn; CHECK: check.idx: 48749d6e3ebSFlorian Hahn; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IDX:%.*]], 5 48849d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]] 48949d6e3ebSFlorian Hahn; CHECK: check.max: 490fee8f561SFlorian Hahn; CHECK-NEXT: [[IDX_SHL_1:%.*]] = shl nuw nsw i8 [[IDX]], 1 491c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_1]] 492*d2502eb0SNikita Popov; CHECK-NEXT: call void @use(i1 true) 49349d6e3ebSFlorian Hahn; CHECK-NEXT: [[IDX_SHL_2:%.*]] = shl nuw i8 [[IDX]], 2 494c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_SHL_2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_2]] 495c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_MAX_1:%.*]] = icmp ult ptr [[ADD_PTR_SHL_2]], [[MAX]] 49649d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_MAX_1]]) 49749d6e3ebSFlorian Hahn; CHECK-NEXT: [[IDX_SHL_NOT_NUW:%.*]] = shl i8 [[IDX]], 1 498c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_NOT_NUW]] 499c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_MAX_2:%.*]] = icmp ult ptr [[ADD_PTR_SHL_NOT_NUW]], [[MAX]] 50049d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_MAX_2]]) 50149d6e3ebSFlorian Hahn; CHECK-NEXT: [[IDX_SHL_3:%.*]] = shl nuw i8 [[IDX]], 3 502c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_3]] 503c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ult ptr [[ADD_PTR_SHL_3]], [[MAX]] 50449d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_MAX_3]]) 50549d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 50649d6e3ebSFlorian Hahn; 50749d6e3ebSFlorian Hahncheck.0.min: 508c5e1ddb6SFlorian Hahn %add.10 = getelementptr inbounds i32, ptr %src, i32 10 509c5e1ddb6SFlorian Hahn %c.add.10.max = icmp ugt ptr %add.10, %max 51049d6e3ebSFlorian Hahn br i1 %c.add.10.max, label %trap, label %check.idx 51149d6e3ebSFlorian Hahn 51249d6e3ebSFlorian Hahntrap: 51349d6e3ebSFlorian Hahn ret void 51449d6e3ebSFlorian Hahn 515c5e1ddb6SFlorian Hahncheck.idx: 51649d6e3ebSFlorian Hahn %cmp = icmp ult i8 %idx, 5 51749d6e3ebSFlorian Hahn br i1 %cmp, label %check.max, label %trap 51849d6e3ebSFlorian Hahn 519c5e1ddb6SFlorian Hahncheck.max: 520fee8f561SFlorian Hahn %idx.shl.1 = shl nsw nuw i8 %idx, 1 521c5e1ddb6SFlorian Hahn %add.ptr.shl.1 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.1 522c5e1ddb6SFlorian Hahn %c.max.0 = icmp ult ptr %add.ptr.shl.1, %max 52349d6e3ebSFlorian Hahn call void @use(i1 %c.max.0) 52449d6e3ebSFlorian Hahn %idx.shl.2 = shl nuw i8 %idx, 2 525c5e1ddb6SFlorian Hahn %add.ptr.shl.2 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.2 526c5e1ddb6SFlorian Hahn %c.max.1 = icmp ult ptr %add.ptr.shl.2, %max 52749d6e3ebSFlorian Hahn call void @use(i1 %c.max.1) 52849d6e3ebSFlorian Hahn %idx.shl.not.nuw = shl i8 %idx, 1 529c5e1ddb6SFlorian Hahn %add.ptr.shl.not.nuw = getelementptr inbounds i32, ptr %src, i8 %idx.shl.not.nuw 530c5e1ddb6SFlorian Hahn %c.max.2 = icmp ult ptr %add.ptr.shl.not.nuw, %max 53149d6e3ebSFlorian Hahn call void @use(i1 %c.max.2) 53249d6e3ebSFlorian Hahn %idx.shl.3 = shl nuw i8 %idx, 3 533c5e1ddb6SFlorian Hahn %add.ptr.shl.3 = getelementptr inbounds i32, ptr %src, i8 %idx.shl.3 534c5e1ddb6SFlorian Hahn %c.max.3 = icmp ult ptr %add.ptr.shl.3, %max 53549d6e3ebSFlorian Hahn call void @use(i1 %c.max.3) 53649d6e3ebSFlorian Hahn ret void 53749d6e3ebSFlorian Hahn} 53849d6e3ebSFlorian Hahn 53949d6e3ebSFlorian Hahn; Test which requires decomposing GEP %ptr, ZEXT(SHL()). 540c5e1ddb6SFlorian Hahndefine void @test.ult.gep.shl.zext(ptr readonly %src, ptr readnone %max, i32 %idx, i32 %j) { 54149d6e3ebSFlorian Hahn; CHECK-LABEL: @test.ult.gep.shl.zext( 54249d6e3ebSFlorian Hahn; CHECK-NEXT: check.0.min: 543c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_10:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i32 10 544c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_ADD_10_MAX:%.*]] = icmp ugt ptr [[ADD_10]], [[MAX:%.*]] 54549d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_ADD_10_MAX]], label [[TRAP:%.*]], label [[CHECK_IDX:%.*]] 54649d6e3ebSFlorian Hahn; CHECK: trap: 54749d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 54849d6e3ebSFlorian Hahn; CHECK: check.idx: 54949d6e3ebSFlorian Hahn; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IDX:%.*]], 5 55049d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP]] 55149d6e3ebSFlorian Hahn; CHECK: check.max: 55249d6e3ebSFlorian Hahn; CHECK-NEXT: [[IDX_SHL:%.*]] = shl nuw i32 [[IDX]], 1 55349d6e3ebSFlorian Hahn; CHECK-NEXT: [[EXT_1:%.*]] = zext i32 [[IDX_SHL]] to i64 554c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_SHL:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_1]] 55549d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 true) 55649d6e3ebSFlorian Hahn; CHECK-NEXT: [[IDX_SHL_NOT_NUW:%.*]] = shl i32 [[IDX]], 1 55749d6e3ebSFlorian Hahn; CHECK-NEXT: [[EXT_2:%.*]] = zext i32 [[IDX_SHL_NOT_NUW]] to i64 558c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_SHL_NOT_NUW:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_2]] 559c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_MAX_1:%.*]] = icmp ult ptr [[ADD_PTR_SHL_NOT_NUW]], [[MAX]] 56049d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_MAX_1]]) 56149d6e3ebSFlorian Hahn; CHECK-NEXT: [[IDX_SHL_3:%.*]] = shl nuw i32 [[IDX]], 2 56249d6e3ebSFlorian Hahn; CHECK-NEXT: [[EXT_3:%.*]] = zext i32 [[IDX_SHL_3]] to i64 563c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_SHL_3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[EXT_3]] 564c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_MAX_2:%.*]] = icmp ult ptr [[ADD_PTR_SHL_3]], [[MAX]] 56549d6e3ebSFlorian Hahn; CHECK-NEXT: call void @use(i1 [[C_MAX_2]]) 56649d6e3ebSFlorian Hahn; CHECK-NEXT: ret void 56749d6e3ebSFlorian Hahn; 56849d6e3ebSFlorian Hahncheck.0.min: 569c5e1ddb6SFlorian Hahn %add.10 = getelementptr inbounds i32, ptr %src, i32 10 570c5e1ddb6SFlorian Hahn %c.add.10.max = icmp ugt ptr %add.10, %max 57149d6e3ebSFlorian Hahn br i1 %c.add.10.max, label %trap, label %check.idx 57249d6e3ebSFlorian Hahn 57349d6e3ebSFlorian Hahntrap: 57449d6e3ebSFlorian Hahn ret void 57549d6e3ebSFlorian Hahn 576c5e1ddb6SFlorian Hahncheck.idx: 57749d6e3ebSFlorian Hahn %cmp = icmp ult i32 %idx, 5 57849d6e3ebSFlorian Hahn br i1 %cmp, label %check.max, label %trap 57949d6e3ebSFlorian Hahn 580c5e1ddb6SFlorian Hahncheck.max: 58149d6e3ebSFlorian Hahn %idx.shl = shl nuw i32 %idx, 1 58249d6e3ebSFlorian Hahn %ext.1 = zext i32 %idx.shl to i64 583c5e1ddb6SFlorian Hahn %add.ptr.shl = getelementptr inbounds i32, ptr %src, i64 %ext.1 584c5e1ddb6SFlorian Hahn %c.max.0 = icmp ult ptr %add.ptr.shl, %max 58549d6e3ebSFlorian Hahn call void @use(i1 %c.max.0) 58649d6e3ebSFlorian Hahn %idx.shl.not.nuw = shl i32 %idx, 1 58749d6e3ebSFlorian Hahn %ext.2 = zext i32 %idx.shl.not.nuw to i64 588c5e1ddb6SFlorian Hahn %add.ptr.shl.not.nuw = getelementptr inbounds i32, ptr %src, i64 %ext.2 589c5e1ddb6SFlorian Hahn %c.max.1 = icmp ult ptr %add.ptr.shl.not.nuw, %max 59049d6e3ebSFlorian Hahn call void @use(i1 %c.max.1) 59149d6e3ebSFlorian Hahn %idx.shl.3 = shl nuw i32 %idx, 2 59249d6e3ebSFlorian Hahn %ext.3 = zext i32 %idx.shl.3 to i64 593c5e1ddb6SFlorian Hahn %add.ptr.shl.3 = getelementptr inbounds i32, ptr %src, i64 %ext.3 594c5e1ddb6SFlorian Hahn %c.max.2 = icmp ult ptr %add.ptr.shl.3, %max 59549d6e3ebSFlorian Hahn call void @use(i1 %c.max.2) 59649d6e3ebSFlorian Hahn ret void 59749d6e3ebSFlorian Hahn} 59849d6e3ebSFlorian Hahn 59949d6e3ebSFlorian Hahn; Make sure non-constant shift amounts are handled correctly. 600c5e1ddb6SFlorian Hahndefine i1 @test.ult.gep.shl.nonconst.zext(i16 %B, ptr readonly %src, ptr readnone %max, i16 %idx, i16 %j) { 60149d6e3ebSFlorian Hahn; CHECK-LABEL: @test.ult.gep.shl.nonconst.zext( 60249d6e3ebSFlorian Hahn; CHECK-NEXT: check.0.min: 603c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_10:%.*]] = getelementptr inbounds i16, ptr [[SRC:%.*]], i16 10 604c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_ADD_10_MAX:%.*]] = icmp ugt ptr [[ADD_10]], [[MAX:%.*]] 60549d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[C_ADD_10_MAX]], label [[EXIT_1:%.*]], label [[CHECK_IDX:%.*]] 60649d6e3ebSFlorian Hahn; CHECK: exit.1: 60749d6e3ebSFlorian Hahn; CHECK-NEXT: ret i1 true 60849d6e3ebSFlorian Hahn; CHECK: check.idx: 60949d6e3ebSFlorian Hahn; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[IDX:%.*]], 5 61049d6e3ebSFlorian Hahn; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_MAX:%.*]], label [[TRAP:%.*]] 61149d6e3ebSFlorian Hahn; CHECK: check.max: 61249d6e3ebSFlorian Hahn; CHECK-NEXT: [[IDX_SHL:%.*]] = shl nuw i16 [[IDX]], [[B:%.*]] 61349d6e3ebSFlorian Hahn; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[IDX_SHL]] to i64 614c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_SHL:%.*]] = getelementptr inbounds i16, ptr [[SRC]], i64 [[EXT]] 615c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_MAX:%.*]] = icmp ult ptr [[ADD_PTR_SHL]], [[MAX]] 61649d6e3ebSFlorian Hahn; CHECK-NEXT: ret i1 [[C_MAX]] 61749d6e3ebSFlorian Hahn; CHECK: trap: 61849d6e3ebSFlorian Hahn; CHECK-NEXT: [[IDX_SHL_1:%.*]] = shl nuw i16 [[IDX]], [[B]] 61949d6e3ebSFlorian Hahn; CHECK-NEXT: [[EXT_1:%.*]] = zext i16 [[IDX_SHL_1]] to i64 620c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i16, ptr [[SRC]], i64 [[EXT_1]] 621c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[C_MAX_1:%.*]] = icmp ult ptr [[ADD_PTR_SHL_1]], [[MAX]] 62249d6e3ebSFlorian Hahn; CHECK-NEXT: ret i1 [[C_MAX_1]] 62349d6e3ebSFlorian Hahn; 62449d6e3ebSFlorian Hahncheck.0.min: 625c5e1ddb6SFlorian Hahn %add.10 = getelementptr inbounds i16, ptr %src, i16 10 626c5e1ddb6SFlorian Hahn %c.add.10.max = icmp ugt ptr %add.10, %max 62749d6e3ebSFlorian Hahn br i1 %c.add.10.max, label %exit.1, label %check.idx 62849d6e3ebSFlorian Hahn 62949d6e3ebSFlorian Hahnexit.1: 63049d6e3ebSFlorian Hahn ret i1 true 63149d6e3ebSFlorian Hahn 632c5e1ddb6SFlorian Hahncheck.idx: 63349d6e3ebSFlorian Hahn %cmp = icmp ult i16 %idx, 5 63449d6e3ebSFlorian Hahn br i1 %cmp, label %check.max, label %trap 63549d6e3ebSFlorian Hahn 636c5e1ddb6SFlorian Hahncheck.max: 63749d6e3ebSFlorian Hahn %idx.shl = shl nuw i16 %idx, %B 63849d6e3ebSFlorian Hahn %ext = zext i16 %idx.shl to i64 639c5e1ddb6SFlorian Hahn %add.ptr.shl = getelementptr inbounds i16, ptr %src, i64 %ext 640c5e1ddb6SFlorian Hahn %c.max = icmp ult ptr %add.ptr.shl, %max 64149d6e3ebSFlorian Hahn ret i1 %c.max 64249d6e3ebSFlorian Hahn 643c5e1ddb6SFlorian Hahntrap: 64449d6e3ebSFlorian Hahn %idx.shl.1 = shl nuw i16 %idx, %B 64549d6e3ebSFlorian Hahn %ext.1 = zext i16 %idx.shl.1 to i64 646c5e1ddb6SFlorian Hahn %add.ptr.shl.1 = getelementptr inbounds i16, ptr %src, i64 %ext.1 647c5e1ddb6SFlorian Hahn %c.max.1 = icmp ult ptr %add.ptr.shl.1, %max 64849d6e3ebSFlorian Hahn ret i1 %c.max.1 64949d6e3ebSFlorian Hahn} 65049d6e3ebSFlorian Hahn 65149d6e3ebSFlorian Hahndeclare void @use(i1) 652