1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2;RUN: opt < %s -jump-threading -S | FileCheck %s 3 4 5declare void @bar(...) 6declare void @baz(...) 7 8; Make sure we thread the end of the bar block to the end of the function. 9define void @test1(i32 %x) { 10; CHECK-LABEL: @test1( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 9 13; CHECK-NEXT: br i1 [[CMP]], label [[IF_END_THREAD:%.*]], label [[IF_END:%.*]] 14; CHECK: if.end.thread: 15; CHECK-NEXT: call void (...) @bar() 16; CHECK-NEXT: br label [[IF_END4:%.*]] 17; CHECK: if.end: 18; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], -3 19; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X_OFF]], 5 20; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN3:%.*]], label [[IF_END4]] 21; CHECK: if.then3: 22; CHECK-NEXT: call void (...) @baz() 23; CHECK-NEXT: br label [[IF_END4]] 24; CHECK: if.end4: 25; CHECK-NEXT: ret void 26; 27entry: 28 %cmp = icmp sgt i32 %x, 9 29 br i1 %cmp, label %if.then, label %if.end 30 31if.then: ; preds = %entry 32 call void (...) @bar() 33 br label %if.end 34 35if.end: ; preds = %if.then, %entry 36 %x.off = add i32 %x, -3 37 %0 = icmp ult i32 %x.off, 5 38 br i1 %0, label %if.then3, label %if.end4 39 40if.then3: ; preds = %if.end 41 call void (...) @baz() 42 br label %if.end4 43 44if.end4: ; preds = %if.then3, %if.end 45 ret void 46} 47 48; Make sure we thread the false side of the first if to the end of the function. 49define void @test2(i32 %x) { 50; CHECK-LABEL: @test2( 51; CHECK-NEXT: entry: 52; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 9 53; CHECK-NEXT: br i1 [[CMP]], label [[IF_END:%.*]], label [[IF_END4:%.*]] 54; CHECK: if.end: 55; CHECK-NEXT: call void (...) @bar() 56; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], -3 57; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X_OFF]], 5 58; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN3:%.*]], label [[IF_END4]] 59; CHECK: if.then3: 60; CHECK-NEXT: call void (...) @baz() 61; CHECK-NEXT: br label [[IF_END4]] 62; CHECK: if.end4: 63; CHECK-NEXT: ret void 64; 65entry: 66 %cmp = icmp slt i32 %x, 9 67 br i1 %cmp, label %if.then, label %if.end 68 69if.then: ; preds = %entry 70 call void (...) @bar() 71 br label %if.end 72 73if.end: ; preds = %if.then, %entry 74 %x.off = add i32 %x, -3 75 %0 = icmp ult i32 %x.off, 5 76 br i1 %0, label %if.then3, label %if.end4 77 78if.then3: ; preds = %if.end 79 call void (...) @baz() 80 br label %if.end4 81 82if.end4: ; preds = %if.then3, %if.end 83 ret void 84} 85 86; Negative test to make sure we don't thread when the ranges overlap. 87define void @test3(i32 %x) { 88; CHECK-LABEL: @test3( 89; CHECK-NEXT: entry: 90; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 6 91; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 92; CHECK: if.then: 93; CHECK-NEXT: call void (...) @bar() 94; CHECK-NEXT: br label [[IF_END]] 95; CHECK: if.end: 96; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X]], -3 97; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[X_OFF]], 5 98; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]] 99; CHECK: if.then3: 100; CHECK-NEXT: call void (...) @baz() 101; CHECK-NEXT: br label [[IF_END4]] 102; CHECK: if.end4: 103; CHECK-NEXT: ret void 104; 105entry: 106 %cmp = icmp sgt i32 %x, 6 107 br i1 %cmp, label %if.then, label %if.end 108 109if.then: ; preds = %entry 110 call void (...) @bar() 111 br label %if.end 112 113if.end: ; preds = %if.then, %entry 114 %x.off = add i32 %x, -3 115 %0 = icmp ult i32 %x.off, 5 116 br i1 %0, label %if.then3, label %if.end4 117 118if.then3: ; preds = %if.end 119 call void (...) @baz() 120 br label %if.end4 121 122if.end4: ; preds = %if.then3, %if.end 123 ret void 124} 125 126