brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.3 KiB · 09394a9 Raw
298 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=jump-threading,verify < %s | FileCheck %s3 4target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"5target triple = "x86_64-unknown-linux-gnu"6 7@a = global i32 0, align 48 9; Verify that we branch (twice) on cond2 without checking ptr.10; Verify that we eliminate "bb.file".11 12define void @foo(i32 %cond1, i32 %cond2) {13; CHECK-LABEL: @foo(14; CHECK-NEXT:  entry:15; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[COND1:%.*]], 016; CHECK-NEXT:    br i1 [[TOBOOL]], label [[BB_COND2_THREAD:%.*]], label [[BB_COND2:%.*]]17; CHECK:       bb.cond2:18; CHECK-NEXT:    call void @f1()19; CHECK-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[COND2:%.*]], 020; CHECK-NEXT:    br i1 [[TOBOOL1]], label [[BB_F4:%.*]], label [[BB_F2:%.*]]21; CHECK:       bb.cond2.thread:22; CHECK-NEXT:    [[TOBOOL12:%.*]] = icmp eq i32 [[COND2]], 023; CHECK-NEXT:    br i1 [[TOBOOL12]], label [[BB_F3:%.*]], label [[BB_F2]]24; CHECK:       bb.f2:25; CHECK-NEXT:    call void @f2()26; CHECK-NEXT:    br label [[EXIT:%.*]]27; CHECK:       bb.f3:28; CHECK-NEXT:    call void @f3()29; CHECK-NEXT:    br label [[EXIT]]30; CHECK:       bb.f4:31; CHECK-NEXT:    [[PTR3:%.*]] = phi ptr [ null, [[BB_COND2]] ]32; CHECK-NEXT:    call void @f4()33; CHECK-NEXT:    br label [[EXIT]]34; CHECK:       exit:35; CHECK-NEXT:    ret void36;37entry:38  %tobool = icmp eq i32 %cond1, 039  br i1 %tobool, label %bb.cond2, label %bb.f140 41bb.f1:42  call void @f1()43  br label %bb.cond244 45bb.cond2:46  %ptr = phi ptr [ null, %bb.f1 ], [ @a, %entry ]47  %tobool1 = icmp eq i32 %cond2, 048  br i1 %tobool1, label %bb.file, label %bb.f249 50bb.f2:51  call void @f2()52  br label %exit53 54bb.file:55  %cmp = icmp eq ptr %ptr, null56  br i1 %cmp, label %bb.f4, label %bb.f357 58bb.f3:59  call void @f3()60  br label %exit61 62bb.f4:63  call void @f4()64  br label %exit65 66exit:67  ret void68}69 70declare void @f1()71declare void @f2()72declare void @f3()73declare void @f4()74 75 76; Verify that we branch (twice) on cond2 without checking tobool again.77; Verify that we eliminate "bb.cond1again".78 79define void @foo2(i32 %cond1, i32 %cond2) {80; CHECK-LABEL: @foo2(81; CHECK-NEXT:  entry:82; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[COND1:%.*]], 083; CHECK-NEXT:    br i1 [[TOBOOL]], label [[BB_COND2:%.*]], label [[BB_COND2_THREAD:%.*]]84; CHECK:       bb.cond2:85; CHECK-NEXT:    call void @f1()86; CHECK-NEXT:    [[TOBOOL1:%.*]] = icmp eq i32 [[COND2:%.*]], 087; CHECK-NEXT:    br i1 [[TOBOOL1]], label [[EXIT:%.*]], label [[BB_F3:%.*]]88; CHECK:       bb.cond2.thread:89; CHECK-NEXT:    call void @f2()90; CHECK-NEXT:    [[TOBOOL11:%.*]] = icmp eq i32 [[COND2]], 091; CHECK-NEXT:    br i1 [[TOBOOL11]], label [[EXIT]], label [[BB_F4:%.*]]92; CHECK:       bb.f3:93; CHECK-NEXT:    call void @f3()94; CHECK-NEXT:    br label [[EXIT]]95; CHECK:       bb.f4:96; CHECK-NEXT:    call void @f4()97; CHECK-NEXT:    br label [[EXIT]]98; CHECK:       exit:99; CHECK-NEXT:    ret void100;101entry:102  %tobool = icmp ne i32 %cond1, 0103  br i1 %tobool, label %bb.f1, label %bb.f2104 105bb.f1:106  call void @f1()107  br label %bb.cond2108 109bb.f2:110  call void @f2()111  br label %bb.cond2112 113bb.cond2:114  %tobool1 = icmp eq i32 %cond2, 0115  br i1 %tobool1, label %exit, label %bb.cond1again116 117bb.cond1again:118  br i1 %tobool, label %bb.f3, label %bb.f4119 120bb.f3:121  call void @f3()122  br label %exit123 124bb.f4:125  call void @f4()126  br label %exit127 128exit:129  ret void130}131 132 133; Verify that we thread the edge correctly.  We used to evaluate constant134; expressions like:135;136;   icmp ugt ptr null, inttoptr (i64 4 to ptr)137;138; as "true", causing jump threading to a wrong destination.139 140define void @icmp_ult_null_constexpr(ptr %arg1, ptr %arg2) {141; CHECK-LABEL: @icmp_ult_null_constexpr(142; CHECK-NEXT:  entry:143; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq ptr [[ARG1:%.*]], null144; CHECK-NEXT:    br i1 [[CMP1]], label [[BB_END_THREAD:%.*]], label [[BB_END:%.*]]145; CHECK:       bb_end:146; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne ptr [[ARG2:%.*]], null147; CHECK-NEXT:    br i1 [[CMP2]], label [[BB_CONT:%.*]], label [[BB_BAR2:%.*]]148; CHECK:       bb_end.thread:149; CHECK-NEXT:    call void @bar(i32 1)150; CHECK-NEXT:    [[CMP21:%.*]] = icmp ne ptr [[ARG2]], null151; CHECK-NEXT:    br i1 [[CMP21]], label [[BB_EXIT:%.*]], label [[BB_BAR2]]152; CHECK:       bb_bar2:153; CHECK-NEXT:    call void @bar(i32 2)154; CHECK-NEXT:    br label [[BB_EXIT]]155; CHECK:       bb_cont:156; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult ptr [[ARG1]], inttoptr (i64 4 to ptr)157; CHECK-NEXT:    br i1 [[CMP3]], label [[BB_EXIT]], label [[BB_BAR3:%.*]]158; CHECK:       bb_bar3:159; CHECK-NEXT:    call void @bar(i32 3)160; CHECK-NEXT:    br label [[BB_EXIT]]161; CHECK:       bb_exit:162; CHECK-NEXT:    ret void163;164entry:165  %cmp1 = icmp eq ptr %arg1, null166  br i1 %cmp1, label %bb_bar1, label %bb_end167 168bb_bar1:169  call void @bar(i32 1)170  br label %bb_end171 172bb_end:173  %cmp2 = icmp ne ptr %arg2, null174  br i1 %cmp2, label %bb_cont, label %bb_bar2175 176bb_bar2:177  call void @bar(i32 2)178  br label %bb_exit179 180bb_cont:181  %cmp3 = icmp ult ptr %arg1, inttoptr (i64 4 to ptr)182  br i1 %cmp3, label %bb_exit, label %bb_bar3183 184bb_bar3:185  call void @bar(i32 3)186  br label %bb_exit187 188bb_exit:189  ret void190}191 192; This is a special-case of the above pattern:193; Null is guaranteed to be unsigned <= all values.194 195define void @icmp_ule_null_constexpr(ptr %arg1, ptr %arg2) {196; CHECK-LABEL: @icmp_ule_null_constexpr(197; CHECK-NEXT:  entry:198; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq ptr [[ARG1:%.*]], null199; CHECK-NEXT:    br i1 [[CMP1]], label [[BB_END_THREAD:%.*]], label [[BB_END:%.*]]200; CHECK:       bb_end:201; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne ptr [[ARG2:%.*]], null202; CHECK-NEXT:    br i1 [[CMP2]], label [[BB_CONT:%.*]], label [[BB_BAR2:%.*]]203; CHECK:       bb_end.thread:204; CHECK-NEXT:    call void @bar(i32 1)205; CHECK-NEXT:    [[CMP21:%.*]] = icmp ne ptr [[ARG2]], null206; CHECK-NEXT:    br i1 [[CMP21]], label [[BB_EXIT:%.*]], label [[BB_BAR2]]207; CHECK:       bb_bar2:208; CHECK-NEXT:    call void @bar(i32 2)209; CHECK-NEXT:    br label [[BB_EXIT]]210; CHECK:       bb_cont:211; CHECK-NEXT:    [[CMP3:%.*]] = icmp ule ptr [[ARG1]], inttoptr (i64 4 to ptr)212; CHECK-NEXT:    br i1 [[CMP3]], label [[BB_EXIT]], label [[BB_BAR3:%.*]]213; CHECK:       bb_bar3:214; CHECK-NEXT:    call void @bar(i32 3)215; CHECK-NEXT:    br label [[BB_EXIT]]216; CHECK:       bb_exit:217; CHECK-NEXT:    ret void218;219entry:220  %cmp1 = icmp eq ptr %arg1, null221  br i1 %cmp1, label %bb_bar1, label %bb_end222 223bb_bar1:224  call void @bar(i32 1)225  br label %bb_end226 227bb_end:228  %cmp2 = icmp ne ptr %arg2, null229  br i1 %cmp2, label %bb_cont, label %bb_bar2230 231bb_bar2:232  call void @bar(i32 2)233  br label %bb_exit234 235bb_cont:236  %cmp3 = icmp ule ptr %arg1, inttoptr (i64 4 to ptr)237  br i1 %cmp3, label %bb_exit, label %bb_bar3238 239bb_bar3:240  call void @bar(i32 3)241  br label %bb_exit242 243bb_exit:244  ret void245}246 247declare void @bar(i32)248 249 250;; Test that we skip unconditional PredBB when threading jumps through two251;; successive basic blocks.252 253define i32 @foo4(ptr %0) {254; CHECK-LABEL: @foo4(255; CHECK-NEXT:  entry:256; CHECK-NEXT:    [[SIZE:%.*]] = call i64 @get_size(ptr [[TMP0:%.*]])257; CHECK-NEXT:    [[GOOD:%.*]] = icmp ugt i64 [[SIZE]], 3258; CHECK-NEXT:    br i1 [[GOOD]], label [[PRED_BB:%.*]], label [[PRED_PRED_BB:%.*]]259; CHECK:       pred.pred.bb:260; CHECK-NEXT:    call void @effect()261; CHECK-NEXT:    br label [[PRED_BB]]262; CHECK:       pred.bb:263; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[TMP0]], align 4264; CHECK-NEXT:    br label [[BB:%.*]]265; CHECK:       bb:266; CHECK-NEXT:    call void @effect1(ptr blockaddress(@foo4, [[BB]]))267; CHECK-NEXT:    br i1 [[GOOD]], label [[EXIT:%.*]], label [[EXIT]]268; CHECK:       exit:269; CHECK-NEXT:    ret i32 [[V]]270;271entry:272  %size = call i64 @get_size(ptr %0)273  %good = icmp ugt i64 %size, 3274  br i1 %good, label %pred.bb, label %pred.pred.bb275 276pred.pred.bb:                                        ; preds = %entry277  call void @effect()278  br label %pred.bb279pred.bb:                                             ; preds = %pred.pred.bb, %entry280  %v = load i32, ptr %0281  br label %bb282 283bb:                                                  ; preds = %pred.bb284  call void @effect1(ptr blockaddress(@foo4, %bb))285  br i1 %good, label %cont2, label %cont1286 287cont1:                                               ; preds = %bb288  br i1 %good, label %exit, label %cont2289cont2:                                               ; preds = %bb290  br label %exit291exit:                                                ; preds = %cont1, %cont2292  ret i32 %v293}294 295declare i64 @get_size(ptr)296declare void @effect()297declare void @effect1(ptr)298