1962c6fdaSSanjay Patel; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 21ea84653SJuneyoung Lee; RUN: opt < %s -jump-threading -S -verify | FileCheck %s 31ea84653SJuneyoung Lee 41ea84653SJuneyoung Leetarget datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 51ea84653SJuneyoung Leetarget triple = "x86_64-unknown-linux-gnu" 61ea84653SJuneyoung Lee 71ea84653SJuneyoung Lee@a = global i32 0, align 4 81ea84653SJuneyoung Lee 9962c6fdaSSanjay Patel; Verify that we branch (twice) on cond2 without checking ptr. 10962c6fdaSSanjay Patel; Verify that we eliminate "bb.file". 11962c6fdaSSanjay Patel 121ea84653SJuneyoung Leedefine void @foo(i32 %cond1, i32 %cond2) { 13962c6fdaSSanjay Patel; CHECK-LABEL: @foo( 14962c6fdaSSanjay Patel; CHECK-NEXT: entry: 15962c6fdaSSanjay Patel; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[COND1:%.*]], 0 16962c6fdaSSanjay Patel; CHECK-NEXT: br i1 [[TOBOOL]], label [[BB_COND2_THREAD:%.*]], label [[BB_COND2:%.*]] 17962c6fdaSSanjay Patel; CHECK: bb.cond2: 18962c6fdaSSanjay Patel; CHECK-NEXT: call void @f1() 19962c6fdaSSanjay Patel; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[COND2:%.*]], 0 20962c6fdaSSanjay Patel; CHECK-NEXT: br i1 [[TOBOOL1]], label [[BB_F4:%.*]], label [[BB_F2:%.*]] 21962c6fdaSSanjay Patel; CHECK: bb.cond2.thread: 22962c6fdaSSanjay Patel; CHECK-NEXT: [[TOBOOL12:%.*]] = icmp eq i32 [[COND2]], 0 23962c6fdaSSanjay Patel; CHECK-NEXT: br i1 [[TOBOOL12]], label [[BB_F3:%.*]], label [[BB_F2]] 24962c6fdaSSanjay Patel; CHECK: bb.f2: 25962c6fdaSSanjay Patel; CHECK-NEXT: call void @f2() 26962c6fdaSSanjay Patel; CHECK-NEXT: br label [[EXIT:%.*]] 27962c6fdaSSanjay Patel; CHECK: bb.f3: 28962c6fdaSSanjay Patel; CHECK-NEXT: call void @f3() 29962c6fdaSSanjay Patel; CHECK-NEXT: br label [[EXIT]] 30962c6fdaSSanjay Patel; CHECK: bb.f4: 31962c6fdaSSanjay Patel; CHECK-NEXT: [[PTR3:%.*]] = phi i32* [ null, [[BB_COND2]] ] 32962c6fdaSSanjay Patel; CHECK-NEXT: call void @f4() 33962c6fdaSSanjay Patel; CHECK-NEXT: br label [[EXIT]] 34962c6fdaSSanjay Patel; CHECK: exit: 35962c6fdaSSanjay Patel; CHECK-NEXT: ret void 36962c6fdaSSanjay Patel; 371ea84653SJuneyoung Leeentry: 381ea84653SJuneyoung Lee %tobool = icmp eq i32 %cond1, 0 391ea84653SJuneyoung Lee br i1 %tobool, label %bb.cond2, label %bb.f1 401ea84653SJuneyoung Lee 411ea84653SJuneyoung Leebb.f1: 421ea84653SJuneyoung Lee call void @f1() 431ea84653SJuneyoung Lee br label %bb.cond2 441ea84653SJuneyoung Lee 451ea84653SJuneyoung Leebb.cond2: 461ea84653SJuneyoung Lee %ptr = phi i32* [ null, %bb.f1 ], [ @a, %entry ] 471ea84653SJuneyoung Lee %tobool1 = icmp eq i32 %cond2, 0 481ea84653SJuneyoung Lee br i1 %tobool1, label %bb.file, label %bb.f2 491ea84653SJuneyoung Lee 501ea84653SJuneyoung Leebb.f2: 511ea84653SJuneyoung Lee call void @f2() 521ea84653SJuneyoung Lee br label %exit 531ea84653SJuneyoung Lee 541ea84653SJuneyoung Leebb.file: 551ea84653SJuneyoung Lee %cmp = icmp eq i32* %ptr, null 561ea84653SJuneyoung Lee br i1 %cmp, label %bb.f4, label %bb.f3 571ea84653SJuneyoung Lee 581ea84653SJuneyoung Leebb.f3: 591ea84653SJuneyoung Lee call void @f3() 601ea84653SJuneyoung Lee br label %exit 611ea84653SJuneyoung Lee 621ea84653SJuneyoung Leebb.f4: 631ea84653SJuneyoung Lee call void @f4() 641ea84653SJuneyoung Lee br label %exit 651ea84653SJuneyoung Lee 661ea84653SJuneyoung Leeexit: 671ea84653SJuneyoung Lee ret void 681ea84653SJuneyoung Lee} 691ea84653SJuneyoung Lee 701ea84653SJuneyoung Leedeclare void @f1() 711ea84653SJuneyoung Leedeclare void @f2() 721ea84653SJuneyoung Leedeclare void @f3() 731ea84653SJuneyoung Leedeclare void @f4() 741ea84653SJuneyoung Lee 751ea84653SJuneyoung Lee 76962c6fdaSSanjay Patel; Verify that we branch (twice) on cond2 without checking tobool again. 77962c6fdaSSanjay Patel; Verify that we eliminate "bb.cond1again". 78962c6fdaSSanjay Patel 791ea84653SJuneyoung Leedefine void @foo2(i32 %cond1, i32 %cond2) { 80962c6fdaSSanjay Patel; CHECK-LABEL: @foo2( 81962c6fdaSSanjay Patel; CHECK-NEXT: entry: 82962c6fdaSSanjay Patel; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[COND1:%.*]], 0 83962c6fdaSSanjay Patel; CHECK-NEXT: br i1 [[TOBOOL]], label [[BB_COND2:%.*]], label [[BB_COND2_THREAD:%.*]] 84962c6fdaSSanjay Patel; CHECK: bb.cond2: 85962c6fdaSSanjay Patel; CHECK-NEXT: call void @f1() 86962c6fdaSSanjay Patel; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[COND2:%.*]], 0 87962c6fdaSSanjay Patel; CHECK-NEXT: br i1 [[TOBOOL1]], label [[EXIT:%.*]], label [[BB_F3:%.*]] 88962c6fdaSSanjay Patel; CHECK: bb.cond2.thread: 89962c6fdaSSanjay Patel; CHECK-NEXT: call void @f2() 90962c6fdaSSanjay Patel; CHECK-NEXT: [[TOBOOL11:%.*]] = icmp eq i32 [[COND2]], 0 91962c6fdaSSanjay Patel; CHECK-NEXT: br i1 [[TOBOOL11]], label [[EXIT]], label [[BB_F4:%.*]] 92962c6fdaSSanjay Patel; CHECK: bb.f3: 93962c6fdaSSanjay Patel; CHECK-NEXT: call void @f3() 94962c6fdaSSanjay Patel; CHECK-NEXT: br label [[EXIT]] 95962c6fdaSSanjay Patel; CHECK: bb.f4: 96962c6fdaSSanjay Patel; CHECK-NEXT: call void @f4() 97962c6fdaSSanjay Patel; CHECK-NEXT: br label [[EXIT]] 98962c6fdaSSanjay Patel; CHECK: exit: 99962c6fdaSSanjay Patel; CHECK-NEXT: ret void 100962c6fdaSSanjay Patel; 1011ea84653SJuneyoung Leeentry: 1021ea84653SJuneyoung Lee %tobool = icmp ne i32 %cond1, 0 1031ea84653SJuneyoung Lee br i1 %tobool, label %bb.f1, label %bb.f2 1041ea84653SJuneyoung Lee 1051ea84653SJuneyoung Leebb.f1: 1061ea84653SJuneyoung Lee call void @f1() 1071ea84653SJuneyoung Lee br label %bb.cond2 1081ea84653SJuneyoung Lee 1091ea84653SJuneyoung Leebb.f2: 1101ea84653SJuneyoung Lee call void @f2() 1111ea84653SJuneyoung Lee br label %bb.cond2 1121ea84653SJuneyoung Lee 1131ea84653SJuneyoung Leebb.cond2: 1141ea84653SJuneyoung Lee %tobool1 = icmp eq i32 %cond2, 0 1151ea84653SJuneyoung Lee br i1 %tobool1, label %exit, label %bb.cond1again 1161ea84653SJuneyoung Lee 1171ea84653SJuneyoung Leebb.cond1again: 1181ea84653SJuneyoung Lee br i1 %tobool, label %bb.f3, label %bb.f4 1191ea84653SJuneyoung Lee 1201ea84653SJuneyoung Leebb.f3: 1211ea84653SJuneyoung Lee call void @f3() 1221ea84653SJuneyoung Lee br label %exit 1231ea84653SJuneyoung Lee 1241ea84653SJuneyoung Leebb.f4: 1251ea84653SJuneyoung Lee call void @f4() 1261ea84653SJuneyoung Lee br label %exit 1271ea84653SJuneyoung Lee 1281ea84653SJuneyoung Leeexit: 1291ea84653SJuneyoung Lee ret void 1301ea84653SJuneyoung Lee} 1311ea84653SJuneyoung Lee 1321ea84653SJuneyoung Lee 1331ea84653SJuneyoung Lee; Verify that we do *not* thread any edge. We used to evaluate 1341ea84653SJuneyoung Lee; constant expressions like: 1351ea84653SJuneyoung Lee; 1361ea84653SJuneyoung Lee; icmp ugt i8* null, inttoptr (i64 4 to i8*) 1371ea84653SJuneyoung Lee; 1381ea84653SJuneyoung Lee; as "true", causing jump threading to a wrong destination. 139962c6fdaSSanjay Patel 140a093942cSSanjay Pateldefine void @icmp_ult_null_constexpr(i8* %arg1, i8* %arg2) { 141a093942cSSanjay Patel; CHECK-LABEL: @icmp_ult_null_constexpr( 142a093942cSSanjay Patel; CHECK-NEXT: entry: 143a093942cSSanjay Patel; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8* [[ARG1:%.*]], null 144a093942cSSanjay Patel; CHECK-NEXT: br i1 [[CMP1]], label [[BB_BAR1:%.*]], label [[BB_END:%.*]] 145a093942cSSanjay Patel; CHECK: bb_bar1: 146a093942cSSanjay Patel; CHECK-NEXT: call void @bar(i32 1) 147a093942cSSanjay Patel; CHECK-NEXT: br label [[BB_END]] 148a093942cSSanjay Patel; CHECK: bb_end: 149a093942cSSanjay Patel; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8* [[ARG2:%.*]], null 150a093942cSSanjay Patel; CHECK-NEXT: br i1 [[CMP2]], label [[BB_CONT:%.*]], label [[BB_BAR2:%.*]] 151a093942cSSanjay Patel; CHECK: bb_bar2: 152a093942cSSanjay Patel; CHECK-NEXT: call void @bar(i32 2) 153a093942cSSanjay Patel; CHECK-NEXT: br label [[BB_EXIT:%.*]] 154a093942cSSanjay Patel; CHECK: bb_cont: 155a093942cSSanjay Patel; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i8* [[ARG1]], inttoptr (i64 4 to i8*) 156a093942cSSanjay Patel; CHECK-NEXT: br i1 [[CMP3]], label [[BB_EXIT]], label [[BB_BAR3:%.*]] 157a093942cSSanjay Patel; CHECK: bb_bar3: 158a093942cSSanjay Patel; CHECK-NEXT: call void @bar(i32 3) 159a093942cSSanjay Patel; CHECK-NEXT: br label [[BB_EXIT]] 160a093942cSSanjay Patel; CHECK: bb_exit: 161a093942cSSanjay Patel; CHECK-NEXT: ret void 162a093942cSSanjay Patel; 163a093942cSSanjay Patelentry: 164a093942cSSanjay Patel %cmp1 = icmp eq i8* %arg1, null 165a093942cSSanjay Patel br i1 %cmp1, label %bb_bar1, label %bb_end 166a093942cSSanjay Patel 167a093942cSSanjay Patelbb_bar1: 168a093942cSSanjay Patel call void @bar(i32 1) 169a093942cSSanjay Patel br label %bb_end 170a093942cSSanjay Patel 171a093942cSSanjay Patelbb_end: 172a093942cSSanjay Patel %cmp2 = icmp ne i8* %arg2, null 173a093942cSSanjay Patel br i1 %cmp2, label %bb_cont, label %bb_bar2 174a093942cSSanjay Patel 175a093942cSSanjay Patelbb_bar2: 176a093942cSSanjay Patel call void @bar(i32 2) 177a093942cSSanjay Patel br label %bb_exit 178a093942cSSanjay Patel 179a093942cSSanjay Patelbb_cont: 180a093942cSSanjay Patel %cmp3 = icmp ult i8* %arg1, inttoptr (i64 4 to i8*) 181a093942cSSanjay Patel br i1 %cmp3, label %bb_exit, label %bb_bar3 182a093942cSSanjay Patel 183a093942cSSanjay Patelbb_bar3: 184a093942cSSanjay Patel call void @bar(i32 3) 185a093942cSSanjay Patel br label %bb_exit 186a093942cSSanjay Patel 187a093942cSSanjay Patelbb_exit: 188a093942cSSanjay Patel ret void 189a093942cSSanjay Patel} 190a093942cSSanjay Patel 191*f75b5305SSanjay Patel; This is a special-case of the above pattern: 192a093942cSSanjay Patel; Null is guaranteed to be unsigned <= all values. 193a093942cSSanjay Patel 194a093942cSSanjay Pateldefine void @icmp_ule_null_constexpr(i8* %arg1, i8* %arg2) { 195a093942cSSanjay Patel; CHECK-LABEL: @icmp_ule_null_constexpr( 196962c6fdaSSanjay Patel; CHECK-NEXT: entry: 197962c6fdaSSanjay Patel; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8* [[ARG1:%.*]], null 198*f75b5305SSanjay Patel; CHECK-NEXT: br i1 [[CMP1]], label [[BB_END_THREAD:%.*]], label [[BB_END:%.*]] 199962c6fdaSSanjay Patel; CHECK: bb_end: 200962c6fdaSSanjay Patel; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8* [[ARG2:%.*]], null 201962c6fdaSSanjay Patel; CHECK-NEXT: br i1 [[CMP2]], label [[BB_CONT:%.*]], label [[BB_BAR2:%.*]] 202*f75b5305SSanjay Patel; CHECK: bb_end.thread: 203*f75b5305SSanjay Patel; CHECK-NEXT: call void @bar(i32 1) 204*f75b5305SSanjay Patel; CHECK-NEXT: [[CMP21:%.*]] = icmp ne i8* [[ARG2]], null 205*f75b5305SSanjay Patel; CHECK-NEXT: br i1 [[CMP21]], label [[BB_EXIT:%.*]], label [[BB_BAR2]] 206962c6fdaSSanjay Patel; CHECK: bb_bar2: 207962c6fdaSSanjay Patel; CHECK-NEXT: call void @bar(i32 2) 208*f75b5305SSanjay Patel; CHECK-NEXT: br label [[BB_EXIT]] 209962c6fdaSSanjay Patel; CHECK: bb_cont: 210962c6fdaSSanjay Patel; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i8* [[ARG1]], inttoptr (i64 4 to i8*) 211962c6fdaSSanjay Patel; CHECK-NEXT: br i1 [[CMP3]], label [[BB_EXIT]], label [[BB_BAR3:%.*]] 212962c6fdaSSanjay Patel; CHECK: bb_bar3: 213962c6fdaSSanjay Patel; CHECK-NEXT: call void @bar(i32 3) 214962c6fdaSSanjay Patel; CHECK-NEXT: br label [[BB_EXIT]] 215962c6fdaSSanjay Patel; CHECK: bb_exit: 216962c6fdaSSanjay Patel; CHECK-NEXT: ret void 217962c6fdaSSanjay Patel; 2181ea84653SJuneyoung Leeentry: 2191ea84653SJuneyoung Lee %cmp1 = icmp eq i8* %arg1, null 2201ea84653SJuneyoung Lee br i1 %cmp1, label %bb_bar1, label %bb_end 2211ea84653SJuneyoung Lee 2221ea84653SJuneyoung Leebb_bar1: 2231ea84653SJuneyoung Lee call void @bar(i32 1) 2241ea84653SJuneyoung Lee br label %bb_end 2251ea84653SJuneyoung Lee 2261ea84653SJuneyoung Leebb_end: 2271ea84653SJuneyoung Lee %cmp2 = icmp ne i8* %arg2, null 2281ea84653SJuneyoung Lee br i1 %cmp2, label %bb_cont, label %bb_bar2 2291ea84653SJuneyoung Lee 2301ea84653SJuneyoung Leebb_bar2: 2311ea84653SJuneyoung Lee call void @bar(i32 2) 2321ea84653SJuneyoung Lee br label %bb_exit 2331ea84653SJuneyoung Lee 2341ea84653SJuneyoung Leebb_cont: 2351ea84653SJuneyoung Lee %cmp3 = icmp ule i8* %arg1, inttoptr (i64 4 to i8*) 2361ea84653SJuneyoung Lee br i1 %cmp3, label %bb_exit, label %bb_bar3 2371ea84653SJuneyoung Lee 2381ea84653SJuneyoung Leebb_bar3: 2391ea84653SJuneyoung Lee call void @bar(i32 3) 2401ea84653SJuneyoung Lee br label %bb_exit 2411ea84653SJuneyoung Lee 2421ea84653SJuneyoung Leebb_exit: 2431ea84653SJuneyoung Lee ret void 2441ea84653SJuneyoung Lee} 2451ea84653SJuneyoung Lee 2461ea84653SJuneyoung Leedeclare void @bar(i32) 2471ea84653SJuneyoung Lee 2481ea84653SJuneyoung Lee 2491ea84653SJuneyoung Lee;; Test that we skip unconditional PredBB when threading jumps through two 2501ea84653SJuneyoung Lee;; successive basic blocks. 2511ea84653SJuneyoung Lee 2521ea84653SJuneyoung Leedefine i32 @foo4(i32* %0) { 253962c6fdaSSanjay Patel; CHECK-LABEL: @foo4( 254962c6fdaSSanjay Patel; CHECK-NEXT: entry: 255962c6fdaSSanjay Patel; CHECK-NEXT: [[SIZE:%.*]] = call i64 @get_size(i32* [[TMP0:%.*]]) 256962c6fdaSSanjay Patel; CHECK-NEXT: [[GOOD:%.*]] = icmp ugt i64 [[SIZE]], 3 257962c6fdaSSanjay Patel; CHECK-NEXT: br i1 [[GOOD]], label [[PRED_BB:%.*]], label [[PRED_PRED_BB:%.*]] 258962c6fdaSSanjay Patel; CHECK: pred.pred.bb: 259962c6fdaSSanjay Patel; CHECK-NEXT: call void @effect() 260962c6fdaSSanjay Patel; CHECK-NEXT: br label [[PRED_BB]] 261962c6fdaSSanjay Patel; CHECK: pred.bb: 262962c6fdaSSanjay Patel; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[TMP0]], align 4 263962c6fdaSSanjay Patel; CHECK-NEXT: br label [[BB:%.*]] 264962c6fdaSSanjay Patel; CHECK: bb: 265962c6fdaSSanjay Patel; CHECK-NEXT: call void @effect1(i8* blockaddress(@foo4, [[BB]])) 266962c6fdaSSanjay Patel; CHECK-NEXT: br i1 [[GOOD]], label [[EXIT:%.*]], label [[EXIT]] 267962c6fdaSSanjay Patel; CHECK: exit: 268962c6fdaSSanjay Patel; CHECK-NEXT: ret i32 [[V]] 269962c6fdaSSanjay Patel; 2701ea84653SJuneyoung Leeentry: 2711ea84653SJuneyoung Lee %size = call i64 @get_size(i32* %0) 2721ea84653SJuneyoung Lee %good = icmp ugt i64 %size, 3 2731ea84653SJuneyoung Lee br i1 %good, label %pred.bb, label %pred.pred.bb 2741ea84653SJuneyoung Lee 2751ea84653SJuneyoung Leepred.pred.bb: ; preds = %entry 2761ea84653SJuneyoung Lee call void @effect() 2771ea84653SJuneyoung Lee br label %pred.bb 2781ea84653SJuneyoung Leepred.bb: ; preds = %pred.pred.bb, %entry 2791ea84653SJuneyoung Lee %v = load i32, i32* %0 2801ea84653SJuneyoung Lee br label %bb 2811ea84653SJuneyoung Lee 2821ea84653SJuneyoung Leebb: ; preds = %pred.bb 2831ea84653SJuneyoung Lee call void @effect1(i8* blockaddress(@foo4, %bb)) 2841ea84653SJuneyoung Lee br i1 %good, label %cont2, label %cont1 2851ea84653SJuneyoung Lee 2861ea84653SJuneyoung Leecont1: ; preds = %bb 2871ea84653SJuneyoung Lee br i1 %good, label %exit, label %cont2 2881ea84653SJuneyoung Leecont2: ; preds = %bb 2891ea84653SJuneyoung Lee br label %exit 2901ea84653SJuneyoung Leeexit: ; preds = %cont1, %cont2 2911ea84653SJuneyoung Lee ret i32 %v 2921ea84653SJuneyoung Lee} 2931ea84653SJuneyoung Lee 2941ea84653SJuneyoung Leedeclare i64 @get_size(i32*) 2951ea84653SJuneyoung Leedeclare void @effect() 2961ea84653SJuneyoung Leedeclare void @effect1(i8*) 297