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