173 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=gvn -S | FileCheck %s3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"5target triple = "x86_64-unknown-linux-gnu"6 7declare void @llvm.memset.p0.i8(ptr, i8, i32, i1)8declare void @foo(ptr)9 10define i8 @test(i1 %cmp) {11; CHECK-LABEL: @test(12; CHECK-NEXT: entry:13; CHECK-NEXT: [[P:%.*]] = alloca i814; CHECK-NEXT: store i8 5, ptr [[P]]15; CHECK-NEXT: br label [[HEADER:%.*]]16; CHECK: header:17; CHECK-NEXT: [[V:%.*]] = phi i8 [ 5, [[ENTRY:%.*]] ], [ -5, [[ALIVE:%.*]] ]18; CHECK-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[I_INC:%.*]], [[ALIVE]] ]19; CHECK-NEXT: br i1 [[CMP:%.*]], label [[ALIVE]], label [[DEAD:%.*]]20; CHECK: dead:21; CHECK-NEXT: call void @foo(ptr [[P]])22; CHECK-NEXT: [[I_1:%.*]] = add i8 [[I]], [[V]]23; CHECK-NEXT: br label [[ALIVE]]24; CHECK: alive:25; CHECK-NEXT: [[I_2:%.*]] = phi i8 [ [[I]], [[HEADER]] ], [ [[I_1]], [[DEAD]] ]26; CHECK-NEXT: store i8 -5, ptr [[P]]27; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 1 [[P]], i8 0, i32 1, i1 false)28; CHECK-NEXT: [[I_INC]] = add i8 [[I_2]], 129; CHECK-NEXT: [[CMP_LOOP:%.*]] = icmp ugt i8 [[I_INC]], 10030; CHECK-NEXT: br i1 [[CMP_LOOP]], label [[EXIT:%.*]], label [[HEADER]]31; CHECK: exit:32; CHECK-NEXT: ret i8 033;34 35entry:36 %p = alloca i837 store i8 5, ptr %p38 br label %header39header:40 %i = phi i8 [0, %entry], [%i.inc, %backedge]41 br i1 %cmp, label %alive, label %dead42dead:43 call void @foo(ptr %p)44 %v = load i8, ptr %p, !invariant.load !145 %i.1 = add i8 %i, %v46 br label %alive47alive:48 %i.2 = phi i8 [%i, %header], [%i.1, %dead]49 store i8 -5, ptr %p50 br label %backedge51backedge:52 call void @llvm.memset.p0.i8(ptr align 1 %p, i8 0, i32 1, i1 false)53 %i.inc = add i8 %i.2, 154 %cmp.loop = icmp ugt i8 %i.inc, 10055 br i1 %cmp.loop, label %exit, label %header56exit:57 %res = load i8, ptr %p58 ret i8 %res59}60 61; Check that first two loads are not optimized out while the one marked with62; invariant.load reuses %res163define i8 @test2(i1 %cmp, ptr %p) {64; CHECK-LABEL: @test2(65; CHECK-NEXT: entry:66; CHECK-NEXT: [[RES1:%.*]] = load i8, ptr [[P:%.*]], align 167; CHECK-NEXT: call void @foo(ptr [[P]])68; CHECK-NEXT: br i1 [[CMP:%.*]], label [[B2:%.*]], label [[B1:%.*]]69; CHECK: b1:70; CHECK-NEXT: [[RES2:%.*]] = load i8, ptr [[P]]71; CHECK-NEXT: [[RES3:%.*]] = add i8 [[RES1]], [[RES2]]72; CHECK-NEXT: br label [[ALIVE:%.*]]73; CHECK: b2:74; CHECK-NEXT: [[RES_DEAD:%.*]] = add i8 [[RES1]], [[RES1]]75; CHECK-NEXT: br label [[ALIVE]]76; CHECK: alive:77; CHECK-NEXT: [[RES_PHI:%.*]] = phi i8 [ [[RES3]], [[B1]] ], [ [[RES_DEAD]], [[B2]] ]78; CHECK-NEXT: ret i8 [[RES_PHI]]79;80 81entry:82 %res1 = load i8, ptr %p83 call void @foo(ptr %p)84 br i1 %cmp, label %b2, label %b185b1:86 %res2 = load i8, ptr %p87 %res3 = add i8 %res1, %res288 br label %alive89b2:90 %v = load i8, ptr %p, !invariant.load !191 %res.dead = add i8 %v, %res192 br label %alive93alive:94 %res.phi = phi i8 [%res3, %b1], [%res.dead, %b2]95 ret i8 %res.phi96}97 98; This is essentially the same test case as the above one but with %b1 and %b299; swapped in "br i1 %cmp, label %b1, label %b2" instruction. That helps us to100; ensure that results doesn't depend on visiting order.101define i8 @test3(i1 %cmp, ptr %p) {102; CHECK-LABEL: @test3(103; CHECK-NEXT: entry:104; CHECK-NEXT: [[RES1:%.*]] = load i8, ptr [[P:%.*]], align 1105; CHECK-NEXT: call void @foo(ptr [[P]])106; CHECK-NEXT: br i1 [[CMP:%.*]], label [[B1:%.*]], label [[B2:%.*]]107; CHECK: b1:108; CHECK-NEXT: [[RES2:%.*]] = load i8, ptr [[P]]109; CHECK-NEXT: [[RES3:%.*]] = add i8 [[RES1]], [[RES2]]110; CHECK-NEXT: br label [[ALIVE:%.*]]111; CHECK: b2:112; CHECK-NEXT: [[RES_DEAD:%.*]] = add i8 [[RES1]], [[RES1]]113; CHECK-NEXT: br label [[ALIVE]]114; CHECK: alive:115; CHECK-NEXT: [[RES_PHI:%.*]] = phi i8 [ [[RES3]], [[B1]] ], [ [[RES_DEAD]], [[B2]] ]116; CHECK-NEXT: ret i8 [[RES_PHI]]117;118entry:119 %res1 = load i8, ptr %p120 call void @foo(ptr %p)121 br i1 %cmp, label %b1, label %b2122b1:123 %res2 = load i8, ptr %p124 %res3 = add i8 %res1, %res2125 br label %alive126b2:127 %v = load i8, ptr %p, !invariant.load !1128 %res.dead = add i8 %v, %res1129 br label %alive130alive:131 %res.phi = phi i8 [%res3, %b1], [%res.dead, %b2]132 ret i8 %res.phi133}134 135 136; This is reduced test case catching regression in the first version of the137; fix for invariant loads (https://reviews.llvm.org/D64405).138define void @test4() null_pointer_is_valid {139; CHECK-LABEL: @test4(140; CHECK-NEXT: entry:141; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr inttoptr (i64 8 to ptr), align 4142; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[TMP0]], [[TMP0]]143; CHECK-NEXT: br label [[FUSION_LOOP_HEADER_DIM_1_PREHEADER:%.*]]144; CHECK: fusion.loop_header.dim.1.preheader:145; CHECK-NEXT: [[TMP2:%.*]] = phi float [ [[TMP0]], [[ENTRY:%.*]] ], [ [[DOTPRE:%.*]], [[FUSION_LOOP_HEADER_DIM_1_PREHEADER]] ]146; CHECK-NEXT: [[FUSION_INVAR_ADDRESS_DIM_0_03:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INVAR_INC3:%.*]], [[FUSION_LOOP_HEADER_DIM_1_PREHEADER]] ]147; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x [1 x [4 x float]]], ptr null, i64 0, i64 [[FUSION_INVAR_ADDRESS_DIM_0_03]], i64 0, i64 2148; CHECK-NEXT: [[TMP4:%.*]] = fmul float [[TMP2]], [[TMP2]]149; CHECK-NEXT: [[INVAR_INC3]] = add nuw nsw i64 [[FUSION_INVAR_ADDRESS_DIM_0_03]], 1150; CHECK-NEXT: [[DOTPHI_TRANS_INSERT:%.*]] = getelementptr inbounds [2 x [1 x [4 x float]]], ptr null, i64 0, i64 [[INVAR_INC3]], i64 0, i64 2151; CHECK-NEXT: [[DOTPRE]] = load float, ptr [[DOTPHI_TRANS_INSERT]], align 4, !invariant.load !0152; CHECK-NEXT: br label [[FUSION_LOOP_HEADER_DIM_1_PREHEADER]]153;154entry:155 %0 = getelementptr inbounds [2 x [1 x [4 x float]]], ptr null, i64 0, i64 0, i64 0, i64 2156 %1 = load float, ptr %0, align 4157 %2 = fmul float %1, %1158 br label %fusion.loop_header.dim.1.preheader159 160fusion.loop_header.dim.1.preheader: ; preds = %fusion.loop_header.dim.1.preheader, %entry161 %fusion.invar_address.dim.0.03 = phi i64 [ 0, %entry ], [ %invar.inc3, %fusion.loop_header.dim.1.preheader ]162 %3 = getelementptr inbounds [2 x [1 x [4 x float]]], ptr null, i64 0, i64 %fusion.invar_address.dim.0.03, i64 0, i64 2163 %4 = load float, ptr %3, align 4, !invariant.load !1164 %5 = fmul float %4, %4165 %6 = getelementptr inbounds [2 x [1 x [4 x float]]], ptr null, i64 0, i64 %fusion.invar_address.dim.0.03, i64 0, i64 2166 %7 = load float, ptr %6, align 4, !invariant.load !1167 %8 = fmul float %7, %7168 %invar.inc3 = add nuw nsw i64 %fusion.invar_address.dim.0.03, 1169 br label %fusion.loop_header.dim.1.preheader170}171 172!1 = !{}173