brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.6 KiB · efbc71b Raw
284 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=gvn < %s | FileCheck %s3target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"4 5@sortlist = external global [5001 x i32], align 46 7define void @Bubble() nounwind noinline {8; CHECK-LABEL: @Bubble(9; CHECK-NEXT:  entry:10; CHECK-NEXT:    [[TMP7_PRE:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @sortlist, i32 4), align 411; CHECK-NEXT:    br label [[WHILE_BODY5:%.*]]12; CHECK:       while.body5:13; CHECK-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP7_PRE]], [[ENTRY:%.*]] ], [ [[TMP71:%.*]], [[IF_END:%.*]] ]14; CHECK-NEXT:    [[INDVAR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP6:%.*]], [[IF_END]] ]15; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[INDVAR]], 216; CHECK-NEXT:    [[ARRAYIDX9:%.*]] = getelementptr [5001 x i32], ptr @sortlist, i32 0, i32 [[TMP5]]17; CHECK-NEXT:    [[TMP6]] = add i32 [[INDVAR]], 118; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr [5001 x i32], ptr @sortlist, i32 0, i32 [[TMP6]]19; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX9]], align 420; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[TMP7]], [[TMP10]]21; CHECK-NEXT:    br i1 [[CMP11]], label [[IF_THEN:%.*]], label [[IF_END]]22; CHECK:       if.then:23; CHECK-NEXT:    store i32 [[TMP10]], ptr [[ARRAYIDX]], align 424; CHECK-NEXT:    store i32 [[TMP7]], ptr [[ARRAYIDX9]], align 425; CHECK-NEXT:    br label [[IF_END]]26; CHECK:       if.end:27; CHECK-NEXT:    [[TMP71]] = phi i32 [ [[TMP7]], [[IF_THEN]] ], [ [[TMP10]], [[WHILE_BODY5]] ]28; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[TMP6]], 10029; CHECK-NEXT:    br i1 [[EXITCOND]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY5]]30; CHECK:       while.end.loopexit:31; CHECK-NEXT:    ret void32;33entry:34  br label %while.body535 36while.body5:37  %indvar = phi i32 [ 0, %entry ], [ %tmp6, %if.end ]38  %tmp5 = add i32 %indvar, 239  %arrayidx9 = getelementptr [5001 x i32], ptr @sortlist, i32 0, i32 %tmp540  %tmp6 = add i32 %indvar, 141  %arrayidx = getelementptr [5001 x i32], ptr @sortlist, i32 0, i32 %tmp642  %tmp7 = load i32, ptr %arrayidx, align 443  %tmp10 = load i32, ptr %arrayidx9, align 444  %cmp11 = icmp sgt i32 %tmp7, %tmp1045  br i1 %cmp11, label %if.then, label %if.end46 47if.then:48  store i32 %tmp10, ptr %arrayidx, align 449  store i32 %tmp7, ptr %arrayidx9, align 450  br label %if.end51 52if.end:53  %exitcond = icmp eq i32 %tmp6, 10054  br i1 %exitcond, label %while.end.loopexit, label %while.body555 56while.end.loopexit:57  ret void58}59 60declare void @hold(i32) readonly61declare void @clobber()62 63; This is a classic LICM case64define i32 @test1(i1 %cnd, ptr %p) {65; CHECK-LABEL: @test1(66; CHECK-NEXT:  entry:67; CHECK-NEXT:    [[V1_PRE:%.*]] = load i32, ptr [[P:%.*]], align 468; CHECK-NEXT:    br label [[HEADER:%.*]]69; CHECK:       header:70; CHECK-NEXT:    call void @hold(i32 [[V1_PRE]])71; CHECK-NEXT:    br label [[HEADER]]72;73entry:74  br label %header75 76header:77  %v1 = load i32, ptr %p78  call void @hold(i32 %v1)79  br label %header80}81 82 83; Slightly more complicated case to highlight that MemoryDependenceAnalysis84; can compute availability for internal control flow.  In this case, because85; the value is fully available across the backedge, we only need to establish86; anticipation for the preheader block (which is trivial in this case.)87define i32 @test2(i1 %cnd, ptr %p) {88; CHECK-LABEL: @test2(89; CHECK-NEXT:  entry:90; CHECK-NEXT:    [[V1_PRE:%.*]] = load i32, ptr [[P:%.*]], align 491; CHECK-NEXT:    br label [[HEADER:%.*]]92; CHECK:       header:93; CHECK-NEXT:    call void @hold(i32 [[V1_PRE]])94; CHECK-NEXT:    br i1 [[CND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]95; CHECK:       bb1:96; CHECK-NEXT:    br label [[MERGE:%.*]]97; CHECK:       bb2:98; CHECK-NEXT:    br label [[MERGE]]99; CHECK:       merge:100; CHECK-NEXT:    br label [[HEADER]]101;102entry:103  br label %header104 105header:106  %v1 = load i32, ptr %p107  call void @hold(i32 %v1)108  br i1 %cnd, label %bb1, label %bb2109 110bb1:111  br label %merge112 113bb2:114  br label %merge115 116merge:117  br label %header118}119 120 121; TODO: at the moment, our anticipation check does not handle anything122; other than straight-line unconditional fallthrough.  This particular123; case could be solved through either a backwards anticipation walk or124; use of the "safe to speculate" status (if we annotate the param)125define i32 @test3(i1 %cnd, ptr %p) {126; CHECK-LABEL: @test3(127; CHECK-NEXT:  entry:128; CHECK-NEXT:    br label [[HEADER:%.*]]129; CHECK:       header:130; CHECK-NEXT:    br i1 [[CND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]131; CHECK:       bb1:132; CHECK-NEXT:    br label [[MERGE:%.*]]133; CHECK:       bb2:134; CHECK-NEXT:    br label [[MERGE]]135; CHECK:       merge:136; CHECK-NEXT:    [[V1:%.*]] = load i32, ptr [[P:%.*]], align 4137; CHECK-NEXT:    call void @hold(i32 [[V1]])138; CHECK-NEXT:    br label [[HEADER]]139;140entry:141  br label %header142 143header:144  br i1 %cnd, label %bb1, label %bb2145 146bb1:147  br label %merge148 149bb2:150  br label %merge151 152merge:153  %v1 = load i32, ptr %p154  call void @hold(i32 %v1)155  br label %header156}157 158; Highlight that we can PRE into a latch block when there are multiple159; latches only one of which clobbers an otherwise invariant value.160define i32 @test4(i1 %cnd, ptr %p) {161; CHECK-LABEL: @test4(162; CHECK-NEXT:  entry:163; CHECK-NEXT:    [[V1:%.*]] = load i32, ptr [[P:%.*]], align 4164; CHECK-NEXT:    call void @hold(i32 [[V1]])165; CHECK-NEXT:    br label [[HEADER:%.*]]166; CHECK:       header:167; CHECK-NEXT:    [[V2:%.*]] = phi i32 [ [[V2_PRE:%.*]], [[BB2:%.*]] ], [ [[V2]], [[BB1:%.*]] ], [ [[V1]], [[ENTRY:%.*]] ]168; CHECK-NEXT:    call void @hold(i32 [[V2]])169; CHECK-NEXT:    br i1 [[CND:%.*]], label [[BB1]], label [[BB2]]170; CHECK:       bb1:171; CHECK-NEXT:    br label [[HEADER]]172; CHECK:       bb2:173; CHECK-NEXT:    call void @clobber()174; CHECK-NEXT:    [[V2_PRE]] = load i32, ptr [[P]], align 4175; CHECK-NEXT:    br label [[HEADER]]176;177entry:178  %v1 = load i32, ptr %p179  call void @hold(i32 %v1)180  br label %header181 182header:183  %v2 = load i32, ptr %p184  call void @hold(i32 %v2)185  br i1 %cnd, label %bb1, label %bb2186 187bb1:188  br label %header189 190bb2:191 192  call void @clobber()193  br label %header194}195 196; Highlight the fact that we can PRE into a single clobbering latch block197; even in loop simplify form (though multiple applications of the same198; transformation).199define i32 @test5(i1 %cnd, ptr %p) {200; CHECK-LABEL: @test5(201; CHECK-NEXT:  entry:202; CHECK-NEXT:    [[V1:%.*]] = load i32, ptr [[P:%.*]], align 4203; CHECK-NEXT:    call void @hold(i32 [[V1]])204; CHECK-NEXT:    br label [[HEADER:%.*]]205; CHECK:       header:206; CHECK-NEXT:    [[V2_PRE2:%.*]] = phi i32 [ [[V2_PRE:%.*]], [[MERGE:%.*]] ], [ [[V1]], [[ENTRY:%.*]] ]207; CHECK-NEXT:    call void @hold(i32 [[V2_PRE2]])208; CHECK-NEXT:    br i1 [[CND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]209; CHECK:       bb1:210; CHECK-NEXT:    br label [[MERGE]]211; CHECK:       bb2:212; CHECK-NEXT:    call void @clobber()213; CHECK-NEXT:    [[V2_PRE_PRE:%.*]] = load i32, ptr [[P]], align 4214; CHECK-NEXT:    br label [[MERGE]]215; CHECK:       merge:216; CHECK-NEXT:    [[V2_PRE]] = phi i32 [ [[V2_PRE_PRE]], [[BB2]] ], [ [[V2_PRE2]], [[BB1]] ]217; CHECK-NEXT:    br label [[HEADER]]218;219entry:220  %v1 = load i32, ptr %p221  call void @hold(i32 %v1)222  br label %header223 224header:225  %v2 = load i32, ptr %p226  call void @hold(i32 %v2)227  br i1 %cnd, label %bb1, label %bb2228 229bb1:230  br label %merge231 232bb2:233 234  call void @clobber()235  br label %merge236 237merge:238  br label %header239}240 241declare void @llvm.experimental.guard(i1 %cnd, ...)242 243; These two tests highlight speculation safety when we can not establish244; anticipation (since the original load might actually not execcute)245define i32 @test6a(i1 %cnd, ptr %p) {246; CHECK-LABEL: @test6a(247; CHECK-NEXT:  entry:248; CHECK-NEXT:    br label [[HEADER:%.*]]249; CHECK:       header:250; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[CND:%.*]]) [ "deopt"() ]251; CHECK-NEXT:    [[V1:%.*]] = load i32, ptr [[P:%.*]], align 4252; CHECK-NEXT:    call void @hold(i32 [[V1]])253; CHECK-NEXT:    br label [[HEADER]]254;255entry:256  br label %header257 258header:259  call void (i1, ...) @llvm.experimental.guard(i1 %cnd) ["deopt"()]260  %v1 = load i32, ptr %p261  call void @hold(i32 %v1)262  br label %header263}264 265define i32 @test6b(i1 %cnd, ptr dereferenceable(8) align 4 %p) nofree nosync {266; CHECK-LABEL: @test6b(267; CHECK-NEXT:  entry:268; CHECK-NEXT:    [[V1_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4269; CHECK-NEXT:    br label [[HEADER:%.*]]270; CHECK:       header:271; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[CND:%.*]]) [ "deopt"() ]272; CHECK-NEXT:    call void @hold(i32 [[V1_PRE]])273; CHECK-NEXT:    br label [[HEADER]]274;275entry:276  br label %header277 278header:279  call void (i1, ...) @llvm.experimental.guard(i1 %cnd) ["deopt"()]280  %v1 = load i32, ptr %p281  call void @hold(i32 %v1)282  br label %header283}284