brintos

brintos / llvm-project-archived public Read only

0
0
Text · 55.9 KiB · c498e85 Raw
1242 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=licm -verify-memoryssa < %s | FileCheck %s3; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(loop-simplifycfg,licm)' -verify-memoryssa -S < %s | FileCheck %s4 5target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"6target triple = "x86_64-unknown-linux-gnu"7 8; This test represents the following function:9; void test1(int * __restrict__ a, int * __restrict__ b, int &c, int n) {10;   for (int i = 0; i < n; ++i)11;     if (a[i] > 0)12;       a[i] = c*b[i];13; }14; and we want to hoist the load of %c out of the loop. This can be done only15; because the dereferenceable attribute is on %c.16 17define void @test1(ptr noalias nocapture %a, ptr noalias nocapture readonly %b, ptr nocapture readonly nonnull dereferenceable(4) align 4 %c, i32 %n) #0 {18; CHECK-LABEL: @test1(19; CHECK-NEXT:  entry:20; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 021; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]22; CHECK:       for.body.preheader:23; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[C:%.*]], align 424; CHECK-NEXT:    br label [[FOR_BODY:%.*]]25; CHECK:       for.body:26; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]27; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]28; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 429; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP1]], 030; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]31; CHECK:       if.then:32; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]33; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 434; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP0]]35; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 436; CHECK-NEXT:    br label [[FOR_INC]]37; CHECK:       for.inc:38; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 139; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i3240; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]41; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]42; CHECK:       for.end.loopexit:43; CHECK-NEXT:    br label [[FOR_END]]44; CHECK:       for.end:45; CHECK-NEXT:    ret void46;47entry:48  %cmp11 = icmp sgt i32 %n, 049  br i1 %cmp11, label %for.body, label %for.end50 51for.body:                                         ; preds = %entry, %for.inc52  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]53  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv54  %0 = load i32, ptr %arrayidx, align 455  %cmp1 = icmp sgt i32 %0, 056  br i1 %cmp1, label %if.then, label %for.inc57 58if.then:                                          ; preds = %for.body59  %1 = load i32, ptr %c, align 460  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv61  %2 = load i32, ptr %arrayidx3, align 462  %mul = mul nsw i32 %2, %163  store i32 %mul, ptr %arrayidx, align 464  br label %for.inc65 66for.inc:                                          ; preds = %for.body, %if.then67  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 168  %lftr.wideiv = trunc i64 %indvars.iv.next to i3269  %exitcond = icmp eq i32 %lftr.wideiv, %n70  br i1 %exitcond, label %for.end, label %for.body71 72for.end:                                          ; preds = %for.inc, %entry73  ret void74}75 76; This is the same as @test1, but without the dereferenceable attribute on %c.77; Without this attribute, we should not hoist the load of %c.78define void @test2(ptr noalias nocapture %a, ptr noalias nocapture readonly %b, ptr nocapture readonly nonnull %c, i32 %n) #0 {79; CHECK-LABEL: @test2(80; CHECK-NEXT:  entry:81; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 082; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]83; CHECK:       for.body.preheader:84; CHECK-NEXT:    br label [[FOR_BODY:%.*]]85; CHECK:       for.body:86; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]87; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]88; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 489; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP0]], 090; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]91; CHECK:       if.then:92; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[C:%.*]], align 493; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]94; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 495; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP1]]96; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 497; CHECK-NEXT:    br label [[FOR_INC]]98; CHECK:       for.inc:99; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1100; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32101; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]102; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]103; CHECK:       for.end.loopexit:104; CHECK-NEXT:    br label [[FOR_END]]105; CHECK:       for.end:106; CHECK-NEXT:    ret void107;108entry:109  %cmp11 = icmp sgt i32 %n, 0110  br i1 %cmp11, label %for.body, label %for.end111 112for.body:                                         ; preds = %entry, %for.inc113  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]114  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv115  %0 = load i32, ptr %arrayidx, align 4116  %cmp1 = icmp sgt i32 %0, 0117  br i1 %cmp1, label %if.then, label %for.inc118 119if.then:                                          ; preds = %for.body120  %1 = load i32, ptr %c, align 4121  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv122  %2 = load i32, ptr %arrayidx3, align 4123  %mul = mul nsw i32 %2, %1124  store i32 %mul, ptr %arrayidx, align 4125  br label %for.inc126 127for.inc:                                          ; preds = %for.body, %if.then128  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1129  %lftr.wideiv = trunc i64 %indvars.iv.next to i32130  %exitcond = icmp eq i32 %lftr.wideiv, %n131  br i1 %exitcond, label %for.end, label %for.body132 133for.end:                                          ; preds = %for.inc, %entry134  ret void135}136 137; This test represents the following function:138; void test3(int * restrict a, int * restrict b, int c[static 3], int n) {139;   for (int i = 0; i < n; ++i)140;     if (a[i] > 0)141;       a[i] = cptr b[i];142; }143; and we want to hoist the load of c[2] out of the loop. This can be done only144; because the dereferenceable attribute is on %c.145define void @test3(ptr noalias nocapture %a, ptr noalias nocapture readonly %b, ptr nocapture readonly dereferenceable(12) align 4 %c, i32 %n) #0 {146; CHECK-LABEL: @test3(147; CHECK-NEXT:  entry:148; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0149; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]150; CHECK:       for.body.preheader:151; CHECK-NEXT:    [[C2:%.*]] = getelementptr inbounds i32, ptr [[C:%.*]], i64 2152; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[C2]], align 4153; CHECK-NEXT:    br label [[FOR_BODY:%.*]]154; CHECK:       for.body:155; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]156; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]157; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4158; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP1]], 0159; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]160; CHECK:       if.then:161; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]162; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4163; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP0]]164; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4165; CHECK-NEXT:    br label [[FOR_INC]]166; CHECK:       for.inc:167; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1168; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32169; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]170; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]171; CHECK:       for.end.loopexit:172; CHECK-NEXT:    br label [[FOR_END]]173; CHECK:       for.end:174; CHECK-NEXT:    ret void175;176entry:177  %cmp11 = icmp sgt i32 %n, 0178  br i1 %cmp11, label %for.body, label %for.end179 180for.body:                                         ; preds = %entry, %for.inc181  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]182  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv183  %0 = load i32, ptr %arrayidx, align 4184  %cmp1 = icmp sgt i32 %0, 0185  br i1 %cmp1, label %if.then, label %for.inc186 187if.then:                                          ; preds = %for.body188  %c2 = getelementptr inbounds i32, ptr %c, i64 2189  %1 = load i32, ptr %c2, align 4190  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv191  %2 = load i32, ptr %arrayidx3, align 4192  %mul = mul nsw i32 %2, %1193  store i32 %mul, ptr %arrayidx, align 4194  br label %for.inc195 196for.inc:                                          ; preds = %for.body, %if.then197  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1198  %lftr.wideiv = trunc i64 %indvars.iv.next to i32199  %exitcond = icmp eq i32 %lftr.wideiv, %n200  br i1 %exitcond, label %for.end, label %for.body201 202for.end:                                          ; preds = %for.inc, %entry203  ret void204}205 206; This is the same as @test3, but with a dereferenceable attribute on %c with a207; size too small to cover c[2] (and so we should not hoist it).208define void @test4(ptr noalias nocapture %a, ptr noalias nocapture readonly %b, ptr nocapture readonly dereferenceable(11) %c, i32 %n) #0 {209; CHECK-LABEL: @test4(210; CHECK-NEXT:  entry:211; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0212; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]213; CHECK:       for.body.preheader:214; CHECK-NEXT:    [[C2:%.*]] = getelementptr inbounds i32, ptr [[C:%.*]], i64 2215; CHECK-NEXT:    br label [[FOR_BODY:%.*]]216; CHECK:       for.body:217; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]218; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]219; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4220; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP0]], 0221; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]222; CHECK:       if.then:223; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[C2]], align 4224; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]225; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4226; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP1]]227; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4228; CHECK-NEXT:    br label [[FOR_INC]]229; CHECK:       for.inc:230; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1231; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32232; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]233; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]234; CHECK:       for.end.loopexit:235; CHECK-NEXT:    br label [[FOR_END]]236; CHECK:       for.end:237; CHECK-NEXT:    ret void238;239entry:240  %cmp11 = icmp sgt i32 %n, 0241  br i1 %cmp11, label %for.body, label %for.end242 243for.body:                                         ; preds = %entry, %for.inc244  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]245  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv246  %0 = load i32, ptr %arrayidx, align 4247  %cmp1 = icmp sgt i32 %0, 0248  br i1 %cmp1, label %if.then, label %for.inc249 250if.then:                                          ; preds = %for.body251  %c2 = getelementptr inbounds i32, ptr %c, i64 2252  %1 = load i32, ptr %c2, align 4253  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv254  %2 = load i32, ptr %arrayidx3, align 4255  %mul = mul nsw i32 %2, %1256  store i32 %mul, ptr %arrayidx, align 4257  br label %for.inc258 259for.inc:                                          ; preds = %for.body, %if.then260  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1261  %lftr.wideiv = trunc i64 %indvars.iv.next to i32262  %exitcond = icmp eq i32 %lftr.wideiv, %n263  br i1 %exitcond, label %for.end, label %for.body264 265for.end:                                          ; preds = %for.inc, %entry266  ret void267}268 269; This test represents the following function:270; void test1(int * __restrict__ a, int *b, int &c, int n) {271;   if (c != null)272;     for (int i = 0; i < n; ++i)273;       if (a[i] > 0)274;         a[i] = c*b[i];275; }276; and we want to hoist the load of %c out of the loop. This can be done only277; because the dereferenceable_or_null attribute is on %c and there is a null278; check on %c.279define void @test5(ptr noalias %a, ptr %b, ptr dereferenceable_or_null(4) align 4 %c, i32 %n) #0 {280; CHECK-LABEL: @test5(281; CHECK-NEXT:  entry:282; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne ptr [[C:%.*]], null283; CHECK-NEXT:    br i1 [[NOT_NULL]], label [[NOT_NULL:%.*]], label [[FOR_END:%.*]]284; CHECK:       not.null:285; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0286; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END]]287; CHECK:       for.body.preheader:288; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[C]], align 4289; CHECK-NEXT:    br label [[FOR_BODY:%.*]]290; CHECK:       for.body:291; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]292; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]293; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4294; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP1]], 0295; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]296; CHECK:       if.then:297; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]298; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4299; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP0]]300; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4301; CHECK-NEXT:    br label [[FOR_INC]]302; CHECK:       for.inc:303; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1304; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32305; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]306; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]307; CHECK:       for.end.loopexit:308; CHECK-NEXT:    br label [[FOR_END]]309; CHECK:       for.end:310; CHECK-NEXT:    ret void311;312entry:313  %not_null = icmp ne ptr %c, null314  br i1 %not_null, label %not.null, label %for.end315 316not.null:317  %cmp11 = icmp sgt i32 %n, 0318  br i1 %cmp11, label %for.body, label %for.end319 320for.body:                                         ; preds = %not.null, %for.inc321  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]322  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv323  %0 = load i32, ptr %arrayidx, align 4324  %cmp1 = icmp sgt i32 %0, 0325  br i1 %cmp1, label %if.then, label %for.inc326 327if.then:                                          ; preds = %for.body328  %1 = load i32, ptr %c, align 4329  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv330  %2 = load i32, ptr %arrayidx3, align 4331  %mul = mul nsw i32 %2, %1332  store i32 %mul, ptr %arrayidx, align 4333  br label %for.inc334 335for.inc:                                          ; preds = %for.body, %if.then336  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1337  %lftr.wideiv = trunc i64 %indvars.iv.next to i32338  %exitcond = icmp eq i32 %lftr.wideiv, %n339  br i1 %exitcond, label %for.end, label %for.body340 341for.end:                                          ; preds = %for.inc, %entry, %not.null342  ret void343}344 345; This is the same as @test5, but without the null check on %c.346; Without this check, we should not hoist the load of %c.347 348; This test case has an icmp on c but the use of this comparison is349; not a branch.350define i1 @test6(ptr noalias %a, ptr %b, ptr dereferenceable_or_null(4) %c, i32 %n) #0 {351; CHECK-LABEL: @test6(352; CHECK-NEXT:  entry:353; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne ptr [[C:%.*]], null354; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0355; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]356; CHECK:       for.body.preheader:357; CHECK-NEXT:    br label [[FOR_BODY:%.*]]358; CHECK:       for.body:359; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]360; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]361; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4362; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP0]], 0363; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]364; CHECK:       if.then:365; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[C]], align 4366; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]367; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4368; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP1]]369; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4370; CHECK-NEXT:    br label [[FOR_INC]]371; CHECK:       for.inc:372; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1373; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32374; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]375; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]376; CHECK:       for.end.loopexit:377; CHECK-NEXT:    br label [[FOR_END]]378; CHECK:       for.end:379; CHECK-NEXT:    ret i1 [[NOT_NULL]]380;381entry:382  %not_null = icmp ne ptr %c, null383  %cmp11 = icmp sgt i32 %n, 0384  br i1 %cmp11, label %for.body, label %for.end385 386for.body:                                         ; preds = %entry, %for.inc387  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]388  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv389  %0 = load i32, ptr %arrayidx, align 4390  %cmp1 = icmp sgt i32 %0, 0391  br i1 %cmp1, label %if.then, label %for.inc392 393if.then:                                          ; preds = %for.body394  %1 = load i32, ptr %c, align 4395  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv396  %2 = load i32, ptr %arrayidx3, align 4397  %mul = mul nsw i32 %2, %1398  store i32 %mul, ptr %arrayidx, align 4399  br label %for.inc400 401for.inc:                                          ; preds = %for.body, %if.then402  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1403  %lftr.wideiv = trunc i64 %indvars.iv.next to i32404  %exitcond = icmp eq i32 %lftr.wideiv, %n405  br i1 %exitcond, label %for.end, label %for.body406 407for.end:                                          ; preds = %for.inc, %entry408  ret i1 %not_null409}410 411; This test represents the following function:412; void test1(int * __restrict__ a, int *b, int **cptr, int n) {413;   c = *cptr;414;   for (int i = 0; i < n; ++i)415;     if (a[i] > 0)416;       a[i] = (*c)*b[i];417; }418; and we want to hoist the load of %c out of the loop. This can be done only419; because the dereferenceable meatdata on the c = *cptr load.420define void @test7(ptr noalias %a, ptr %b, ptr %cptr, i32 %n) #0 {421; CHECK-LABEL: @test7(422; CHECK-NEXT:  entry:423; CHECK-NEXT:    [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable [[META0:![0-9]+]], !align [[META0]]424; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0425; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]426; CHECK:       for.body.preheader:427; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[C]], align 4428; CHECK-NEXT:    br label [[FOR_BODY:%.*]]429; CHECK:       for.body:430; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]431; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]432; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4433; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP1]], 0434; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]435; CHECK:       if.then:436; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]437; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4438; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP0]]439; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4440; CHECK-NEXT:    br label [[FOR_INC]]441; CHECK:       for.inc:442; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1443; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32444; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]445; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]446; CHECK:       for.end.loopexit:447; CHECK-NEXT:    br label [[FOR_END]]448; CHECK:       for.end:449; CHECK-NEXT:    ret void450;451entry:452  %c = load ptr, ptr %cptr, !dereferenceable !0, !align !{i64 4}453  %cmp11 = icmp sgt i32 %n, 0454  br i1 %cmp11, label %for.body, label %for.end455 456for.body:                                         ; preds = %entry, %for.inc457  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]458  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv459  %0 = load i32, ptr %arrayidx, align 4460  %cmp1 = icmp sgt i32 %0, 0461  br i1 %cmp1, label %if.then, label %for.inc462 463if.then:                                          ; preds = %for.body464  %1 = load i32, ptr %c, align 4465  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv466  %2 = load i32, ptr %arrayidx3, align 4467  %mul = mul nsw i32 %2, %1468  store i32 %mul, ptr %arrayidx, align 4469  br label %for.inc470 471for.inc:                                          ; preds = %for.body, %if.then472  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1473  %lftr.wideiv = trunc i64 %indvars.iv.next to i32474  %exitcond = icmp eq i32 %lftr.wideiv, %n475  br i1 %exitcond, label %for.end, label %for.body476 477for.end:                                          ; preds = %for.inc, %entry478  ret void479}480 481; This test represents the following function:482; void test1(int * __restrict__ a, int *b, int **cptr, int n) {483;   c = *cptr;484;   if (c != null)485;     for (int i = 0; i < n; ++i)486;       if (a[i] > 0)487;         a[i] = (*c)*b[i];488; }489; and we want to hoist the load of %c out of the loop. This can be done only490; because the dereferenceable_or_null meatdata on the c = *cptr load and there491; is a null check on %c.492define void @test8(ptr noalias %a, ptr %b, ptr %cptr, i32 %n) #0 {493; CHECK-LABEL: @test8(494; CHECK-NEXT:  entry:495; CHECK-NEXT:    [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable_or_null [[META0]], !align [[META0]]496; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne ptr [[C]], null497; CHECK-NEXT:    br i1 [[NOT_NULL]], label [[NOT_NULL:%.*]], label [[FOR_END:%.*]]498; CHECK:       not.null:499; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0500; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END]]501; CHECK:       for.body.preheader:502; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[C]], align 4503; CHECK-NEXT:    br label [[FOR_BODY:%.*]]504; CHECK:       for.body:505; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]506; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]507; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4508; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP1]], 0509; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]510; CHECK:       if.then:511; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]512; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4513; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP0]]514; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4515; CHECK-NEXT:    br label [[FOR_INC]]516; CHECK:       for.inc:517; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1518; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32519; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]520; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]521; CHECK:       for.end.loopexit:522; CHECK-NEXT:    br label [[FOR_END]]523; CHECK:       for.end:524; CHECK-NEXT:    ret void525;526entry:527  %c = load ptr, ptr %cptr, !dereferenceable_or_null !0, !align !{i64 4}528  %not_null = icmp ne ptr %c, null529  br i1 %not_null, label %not.null, label %for.end530 531not.null:532  %cmp11 = icmp sgt i32 %n, 0533  br i1 %cmp11, label %for.body, label %for.end534 535for.body:                                         ; preds = %not.null, %for.inc536  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]537  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv538  %0 = load i32, ptr %arrayidx, align 4539  %cmp1 = icmp sgt i32 %0, 0540  br i1 %cmp1, label %if.then, label %for.inc541 542if.then:                                          ; preds = %for.body543  %1 = load i32, ptr %c, align 4544  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv545  %2 = load i32, ptr %arrayidx3, align 4546  %mul = mul nsw i32 %2, %1547  store i32 %mul, ptr %arrayidx, align 4548  br label %for.inc549 550for.inc:                                          ; preds = %for.body, %if.then551  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1552  %lftr.wideiv = trunc i64 %indvars.iv.next to i32553  %exitcond = icmp eq i32 %lftr.wideiv, %n554  br i1 %exitcond, label %for.end, label %for.body555 556for.end:                                          ; preds = %for.inc, %entry, %not.null557  ret void558}559 560; This is the same as @test8, but without the null check on %c.561; Without this check, we should not hoist the load of %c.562define void @test9(ptr noalias %a, ptr %b, ptr %cptr, i32 %n) #0 {563; CHECK-LABEL: @test9(564; CHECK-NEXT:  entry:565; CHECK-NEXT:    [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable_or_null [[META0]]566; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0567; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]568; CHECK:       for.body.preheader:569; CHECK-NEXT:    br label [[FOR_BODY:%.*]]570; CHECK:       for.body:571; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]572; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]573; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4574; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP0]], 0575; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]576; CHECK:       if.then:577; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[C]], align 4578; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]579; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4580; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP1]]581; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4582; CHECK-NEXT:    br label [[FOR_INC]]583; CHECK:       for.inc:584; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1585; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32586; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]587; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]588; CHECK:       for.end.loopexit:589; CHECK-NEXT:    br label [[FOR_END]]590; CHECK:       for.end:591; CHECK-NEXT:    ret void592;593entry:594  %c = load ptr, ptr %cptr, !dereferenceable_or_null !0595  %cmp11 = icmp sgt i32 %n, 0596  br i1 %cmp11, label %for.body, label %for.end597 598for.body:                                         ; preds = %entry, %for.inc599  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]600  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv601  %0 = load i32, ptr %arrayidx, align 4602  %cmp1 = icmp sgt i32 %0, 0603  br i1 %cmp1, label %if.then, label %for.inc604 605if.then:                                          ; preds = %for.body606  %1 = load i32, ptr %c, align 4607  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv608  %2 = load i32, ptr %arrayidx3, align 4609  %mul = mul nsw i32 %2, %1610  store i32 %mul, ptr %arrayidx, align 4611  br label %for.inc612 613for.inc:                                          ; preds = %for.body, %if.then614  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1615  %lftr.wideiv = trunc i64 %indvars.iv.next to i32616  %exitcond = icmp eq i32 %lftr.wideiv, %n617  br i1 %exitcond, label %for.end, label %for.body618 619for.end:                                          ; preds = %for.inc, %entry620  ret void621}622 623; In this test we should be able to only hoist load from %cptr. We can't hoist624; load from %c because it's dereferenceability can depend on %cmp1 condition.625; By moving it out of the loop we break this dependency and can not rely626; on the dereferenceability anymore.627; In other words this test checks that we strip dereferenceability  metadata628; after hoisting an instruction.629define void @test10(ptr noalias %a, ptr %b, ptr dereferenceable(8) align 8 %cptr, i32 %n) #0 {630; CHECK-LABEL: @test10(631; CHECK-NEXT:  entry:632; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0633; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]634; CHECK:       for.body.preheader:635; CHECK-NEXT:    [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8636; CHECK-NEXT:    br label [[FOR_BODY:%.*]]637; CHECK:       for.body:638; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]639; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]640; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4641; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP0]], 0642; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]643; CHECK:       if.then:644; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[C]], align 4645; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]646; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4647; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP1]]648; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4649; CHECK-NEXT:    br label [[FOR_INC]]650; CHECK:       for.inc:651; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1652; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32653; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]654; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]655; CHECK:       for.end.loopexit:656; CHECK-NEXT:    br label [[FOR_END]]657; CHECK:       for.end:658; CHECK-NEXT:    ret void659;660entry:661  %cmp11 = icmp sgt i32 %n, 0662  br i1 %cmp11, label %for.body, label %for.end663 664for.body:                                         ; preds = %entry, %for.inc665  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]666  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv667  %0 = load i32, ptr %arrayidx, align 4668  %cmp1 = icmp sgt i32 %0, 0669  br i1 %cmp1, label %if.then, label %for.inc670 671if.then:                                          ; preds = %for.body672  %c = load ptr, ptr %cptr, !dereferenceable !0673  %1 = load i32, ptr %c, align 4674  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv675  %2 = load i32, ptr %arrayidx3, align 4676  %mul = mul nsw i32 %2, %1677  store i32 %mul, ptr %arrayidx, align 4678  br label %for.inc679 680for.inc:                                          ; preds = %for.body, %if.then681  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1682  %lftr.wideiv = trunc i64 %indvars.iv.next to i32683  %exitcond = icmp eq i32 %lftr.wideiv, %n684  br i1 %exitcond, label %for.end, label %for.body685 686for.end:                                          ; preds = %for.inc, %entry687  ret void688}689 690define void @test11(ptr noalias %a, ptr %b, ptr dereferenceable(8) %cptr, i32 %n) #0 {691; CHECK-LABEL: @test11(692; CHECK-NEXT:  entry:693; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0694; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]695; CHECK:       for.body.preheader:696; CHECK-NEXT:    [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable [[META0]]697; CHECK-NEXT:    br label [[FOR_BODY:%.*]]698; CHECK:       for.body:699; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]700; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]701; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4702; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP0]], 0703; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]704; CHECK:       if.then:705; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[C]], align 4706; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]707; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4708; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[E]], [[D]]709; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4710; CHECK-NEXT:    br label [[FOR_INC]]711; CHECK:       for.inc:712; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1713; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32714; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]715; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]716; CHECK:       for.end.loopexit:717; CHECK-NEXT:    br label [[FOR_END]]718; CHECK:       for.end:719; CHECK-NEXT:    ret void720;721entry:722  %cmp11 = icmp sgt i32 %n, 0723  br i1 %cmp11, label %for.body, label %for.end724 725 726 727for.body:                                         ; preds = %entry, %for.inc728  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]729  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv730  %0 = load i32, ptr %arrayidx, align 4731  %cmp1 = icmp sgt i32 %0, 0732  %c = load ptr, ptr %cptr, !dereferenceable !0733  br i1 %cmp1, label %if.then, label %for.inc734 735if.then:                                          ; preds = %for.body736  %d = load i32, ptr %c, align 4737  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv738  %e = load i32, ptr %arrayidx3, align 4739  %mul = mul nsw i32 %e, %d740  store i32 %mul, ptr %arrayidx, align 4741  br label %for.inc742 743for.inc:                                          ; preds = %for.body, %if.then744  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1745  %lftr.wideiv = trunc i64 %indvars.iv.next to i32746  %exitcond = icmp eq i32 %lftr.wideiv, %n747  br i1 %exitcond, label %for.end, label %for.body748 749for.end:                                          ; preds = %for.inc, %entry750  ret void751}752 753declare void @llvm.experimental.guard(i1, ...)754 755; Prove non-null ness of %c via a guard, not a branch.756define void @test12(ptr noalias %a, ptr %b, ptr dereferenceable_or_null(4) align 4 %c, i32 %n) #0 {757; CHECK-LABEL: @test12(758; CHECK-NEXT:  entry:759; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne ptr [[C:%.*]], null760; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[NOT_NULL]]) [ "deopt"() ]761; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0762; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]763; CHECK:       for.body.preheader:764; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[C]], align 4765; CHECK-NEXT:    br label [[FOR_BODY:%.*]]766; CHECK:       for.body:767; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]768; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]769; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4770; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP1]], 0771; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]772; CHECK:       if.then:773; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]774; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4775; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP0]]776; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4777; CHECK-NEXT:    br label [[FOR_INC]]778; CHECK:       for.inc:779; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1780; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32781; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]782; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]783; CHECK:       for.end.loopexit:784; CHECK-NEXT:    br label [[FOR_END]]785; CHECK:       for.end:786; CHECK-NEXT:    ret void787;788entry:789  %not_null = icmp ne ptr %c, null790  call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ]791  %cmp11 = icmp sgt i32 %n, 0792  br i1 %cmp11, label %for.body, label %for.end793 794 795 796for.body:                                         ; preds = %entry, %for.inc797  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]798  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv799  %0 = load i32, ptr %arrayidx, align 4800  %cmp1 = icmp sgt i32 %0, 0801  br i1 %cmp1, label %if.then, label %for.inc802 803if.then:                                          ; preds = %for.body804  %1 = load i32, ptr %c, align 4805  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv806  %2 = load i32, ptr %arrayidx3, align 4807  %mul = mul nsw i32 %2, %1808  store i32 %mul, ptr %arrayidx, align 4809  br label %for.inc810 811for.inc:                                          ; preds = %for.body, %if.then812  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1813  %lftr.wideiv = trunc i64 %indvars.iv.next to i32814  %exitcond = icmp eq i32 %lftr.wideiv, %n815  br i1 %exitcond, label %for.end, label %for.body816 817for.end:                                          ; preds = %for.inc, %entry, %entry818  ret void819}820 821; Like @test12, but has a post-dominating guard, which cannot be used822; to prove %c is nonnull at the point of the load.823define void @test13(ptr noalias %a, ptr %b, ptr dereferenceable_or_null(4) %c, i32 %n) #0 {824; CHECK-LABEL: @test13(825; CHECK-NEXT:  entry:826; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne ptr [[C:%.*]], null827; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0828; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]829; CHECK:       for.body.preheader:830; CHECK-NEXT:    br label [[FOR_BODY:%.*]]831; CHECK:       for.body:832; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]833; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]834; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4835; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP0]], 0836; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]837; CHECK:       if.then:838; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[C]], align 4839; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]840; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4841; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP1]]842; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4843; CHECK-NEXT:    br label [[FOR_INC]]844; CHECK:       for.inc:845; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1846; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32847; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]848; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]849; CHECK:       for.end.loopexit:850; CHECK-NEXT:    br label [[FOR_END]]851; CHECK:       for.end:852; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[NOT_NULL]]) [ "deopt"() ]853; CHECK-NEXT:    ret void854;855entry:856  %not_null = icmp ne ptr %c, null857  %cmp11 = icmp sgt i32 %n, 0858  br i1 %cmp11, label %for.body, label %for.end859 860 861for.body:                                         ; preds = %entry, %for.inc862  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]863  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv864  %0 = load i32, ptr %arrayidx, align 4865  %cmp1 = icmp sgt i32 %0, 0866  br i1 %cmp1, label %if.then, label %for.inc867 868if.then:                                          ; preds = %for.body869  %1 = load i32, ptr %c, align 4870  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv871  %2 = load i32, ptr %arrayidx3, align 4872  %mul = mul nsw i32 %2, %1873  store i32 %mul, ptr %arrayidx, align 4874  br label %for.inc875 876for.inc:                                          ; preds = %for.body, %if.then877  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1878  %lftr.wideiv = trunc i64 %indvars.iv.next to i32879  %exitcond = icmp eq i32 %lftr.wideiv, %n880  br i1 %exitcond, label %for.end, label %for.body881 882for.end:                                          ; preds = %for.inc, %entry, %entry883  call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ]884  ret void885}886 887; Check that branch by condition "null check AND something" allows to hoist the888; load.889define void @test14(ptr noalias %a, ptr %b, ptr dereferenceable_or_null(4) align 4 %c, i32 %n, i1 %dummy_cond) #0 {890; CHECK-LABEL: @test14(891; CHECK-NEXT:  entry:892; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne ptr [[C:%.*]], null893; CHECK-NEXT:    [[DUMMY_AND:%.*]] = and i1 [[NOT_NULL]], [[DUMMY_COND:%.*]]894; CHECK-NEXT:    br i1 [[DUMMY_AND]], label [[NOT_NULL:%.*]], label [[FOR_END:%.*]]895; CHECK:       not.null:896; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0897; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END]]898; CHECK:       for.body.preheader:899; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[C]], align 4900; CHECK-NEXT:    br label [[FOR_BODY:%.*]]901; CHECK:       for.body:902; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]903; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]904; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4905; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP1]], 0906; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]907; CHECK:       if.then:908; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]909; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4910; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP0]]911; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4912; CHECK-NEXT:    br label [[FOR_INC]]913; CHECK:       for.inc:914; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1915; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32916; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]917; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]918; CHECK:       for.end.loopexit:919; CHECK-NEXT:    br label [[FOR_END]]920; CHECK:       for.end:921; CHECK-NEXT:    ret void922;923 924entry:925  %not_null = icmp ne ptr %c, null926  %dummy_and = and i1 %not_null, %dummy_cond927  br i1 %dummy_and, label %not.null, label %for.end928 929not.null:930  %cmp11 = icmp sgt i32 %n, 0931  br i1 %cmp11, label %for.body, label %for.end932 933for.body:                                         ; preds = %not.null, %for.inc934  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]935  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv936  %0 = load i32, ptr %arrayidx, align 4937  %cmp1 = icmp sgt i32 %0, 0938  br i1 %cmp1, label %if.then, label %for.inc939 940if.then:                                          ; preds = %for.body941  %1 = load i32, ptr %c, align 4942  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv943  %2 = load i32, ptr %arrayidx3, align 4944  %mul = mul nsw i32 %2, %1945  store i32 %mul, ptr %arrayidx, align 4946  br label %for.inc947 948for.inc:                                          ; preds = %for.body, %if.then949  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1950  %lftr.wideiv = trunc i64 %indvars.iv.next to i32951  %exitcond = icmp eq i32 %lftr.wideiv, %n952  br i1 %exitcond, label %for.end, label %for.body953 954for.end:                                          ; preds = %for.inc, %entry, %not.null955  ret void956}957 958; Check that guard by condition "null check AND something" allows to hoist the959; load.960define void @test15(ptr noalias %a, ptr %b, ptr dereferenceable_or_null(4) align 4 %c, i32 %n, i1 %dummy_cond) #0 {961; CHECK-LABEL: @test15(962; CHECK-NEXT:  entry:963; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne ptr [[C:%.*]], null964; CHECK-NEXT:    [[DUMMY_AND:%.*]] = and i1 [[NOT_NULL]], [[DUMMY_COND:%.*]]965; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[DUMMY_AND]]) [ "deopt"() ]966; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0967; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]968; CHECK:       for.body.preheader:969; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[C]], align 4970; CHECK-NEXT:    br label [[FOR_BODY:%.*]]971; CHECK:       for.body:972; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]973; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]974; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4975; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP1]], 0976; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]977; CHECK:       if.then:978; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]979; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4980; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP0]]981; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 4982; CHECK-NEXT:    br label [[FOR_INC]]983; CHECK:       for.inc:984; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1985; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32986; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]987; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]988; CHECK:       for.end.loopexit:989; CHECK-NEXT:    br label [[FOR_END]]990; CHECK:       for.end:991; CHECK-NEXT:    ret void992;993 994entry:995  %not_null = icmp ne ptr %c, null996  %dummy_and = and i1 %not_null, %dummy_cond997  call void(i1, ...) @llvm.experimental.guard(i1 %dummy_and) [ "deopt"() ]998  %cmp11 = icmp sgt i32 %n, 0999  br i1 %cmp11, label %for.body, label %for.end1000 1001for.body:                                         ; preds = %entry, %for.inc1002  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]1003  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv1004  %0 = load i32, ptr %arrayidx, align 41005  %cmp1 = icmp sgt i32 %0, 01006  br i1 %cmp1, label %if.then, label %for.inc1007 1008if.then:                                          ; preds = %for.body1009  %1 = load i32, ptr %c, align 41010  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv1011  %2 = load i32, ptr %arrayidx3, align 41012  %mul = mul nsw i32 %2, %11013  store i32 %mul, ptr %arrayidx, align 41014  br label %for.inc1015 1016for.inc:                                          ; preds = %for.body, %if.then1017  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 11018  %lftr.wideiv = trunc i64 %indvars.iv.next to i321019  %exitcond = icmp eq i32 %lftr.wideiv, %n1020  br i1 %exitcond, label %for.end, label %for.body1021 1022for.end:                                          ; preds = %for.inc, %entry1023  ret void1024}1025 1026; Ensure that (c == null && other_cond) does not automatically mean that c is1027; non-null in false branch. So the condition ((c == null && other_cond) == false)1028; is not sufficient to conclude that c != null.1029define void @test16(ptr noalias %a, ptr %b, ptr dereferenceable_or_null(4) %c, i32 %n, i1 %dummy_cond) #0 {1030; CHECK-LABEL: @test16(1031; CHECK-NEXT:  entry:1032; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp eq ptr [[C:%.*]], null1033; CHECK-NEXT:    [[DUMMY_AND:%.*]] = and i1 [[NOT_NULL]], [[DUMMY_COND:%.*]]1034; CHECK-NEXT:    br i1 [[DUMMY_AND]], label [[FOR_END:%.*]], label [[NOT_NULL:%.*]]1035; CHECK:       not.null:1036; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 01037; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END]]1038; CHECK:       for.body.preheader:1039; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1040; CHECK:       for.body:1041; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]1042; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]1043; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 41044; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP0]], 01045; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]1046; CHECK:       if.then:1047; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[C]], align 41048; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]1049; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 41050; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP1]]1051; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 41052; CHECK-NEXT:    br label [[FOR_INC]]1053; CHECK:       for.inc:1054; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 11055; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i321056; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]1057; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]1058; CHECK:       for.end.loopexit:1059; CHECK-NEXT:    br label [[FOR_END]]1060; CHECK:       for.end:1061; CHECK-NEXT:    ret void1062;1063 1064entry:1065  %not_null = icmp eq ptr %c, null1066  %dummy_and = and i1 %not_null, %dummy_cond1067  br i1 %dummy_and, label %for.end, label %not.null1068 1069not.null:1070  %cmp11 = icmp sgt i32 %n, 01071  br i1 %cmp11, label %for.body, label %for.end1072 1073for.body:                                         ; preds = %not.null, %for.inc1074  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ]1075  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv1076  %0 = load i32, ptr %arrayidx, align 41077  %cmp1 = icmp sgt i32 %0, 01078  br i1 %cmp1, label %if.then, label %for.inc1079 1080if.then:                                          ; preds = %for.body1081  %1 = load i32, ptr %c, align 41082  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv1083  %2 = load i32, ptr %arrayidx3, align 41084  %mul = mul nsw i32 %2, %11085  store i32 %mul, ptr %arrayidx, align 41086  br label %for.inc1087 1088for.inc:                                          ; preds = %for.body, %if.then1089  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 11090  %lftr.wideiv = trunc i64 %indvars.iv.next to i321091  %exitcond = icmp eq i32 %lftr.wideiv, %n1092  br i1 %exitcond, label %for.end, label %for.body1093 1094for.end:                                          ; preds = %for.inc, %entry, %not.null1095  ret void1096}1097 1098; Ensure that (c == null && other_cond) does not automatically mean that c is1099; non-null in false branch. So the condition ((c == null && other_cond) == false)1100; is not sufficient to conclude that c != null.1101define void @test17(ptr noalias %a, ptr %b, ptr dereferenceable_or_null(4) %c, i32 %n, i1 %dummy_cond) #0 {1102; CHECK-LABEL: @test17(1103; CHECK-NEXT:  entry:1104; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp eq ptr [[C:%.*]], null1105; CHECK-NEXT:    [[DUMMY_AND:%.*]] = and i1 [[NOT_NULL]], [[DUMMY_COND:%.*]]1106; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[DUMMY_AND]]) [ "deopt"() ]1107; CHECK-NEXT:    [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 01108; CHECK-NEXT:    br i1 [[CMP11]], label [[FOR_END:%.*]], label [[FOR_BODY_PREHEADER:%.*]]1109; CHECK:       for.body.preheader:1110; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1111; CHECK:       for.body:1112; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]1113; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]1114; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 41115; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[TMP0]], 01116; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]1117; CHECK:       if.then:1118; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[C]], align 41119; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i64 [[INDVARS_IV]]1120; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 41121; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP2]], [[TMP1]]1122; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX]], align 41123; CHECK-NEXT:    br label [[FOR_INC]]1124; CHECK:       for.inc:1125; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 11126; CHECK-NEXT:    [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i321127; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]1128; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]1129; CHECK:       for.end.loopexit:1130; CHECK-NEXT:    br label [[FOR_END]]1131; CHECK:       for.end:1132; CHECK-NEXT:    ret void1133;1134 1135entry:1136  %not_null = icmp eq ptr %c, null1137  %dummy_and = and i1 %not_null, %dummy_cond1138  call void(i1, ...) @llvm.experimental.guard(i1 %dummy_and) [ "deopt"() ]1139  %cmp11 = icmp sgt i32 %n, 01140  br i1 %cmp11, label %for.end, label %for.body1141 1142for.body:                                         ; preds = %entry, %for.inc1143  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]1144  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv1145  %0 = load i32, ptr %arrayidx, align 41146  %cmp1 = icmp sgt i32 %0, 01147  br i1 %cmp1, label %if.then, label %for.inc1148 1149if.then:                                          ; preds = %for.body1150  %1 = load i32, ptr %c, align 41151  %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv1152  %2 = load i32, ptr %arrayidx3, align 41153  %mul = mul nsw i32 %2, %11154  store i32 %mul, ptr %arrayidx, align 41155  br label %for.inc1156 1157for.inc:                                          ; preds = %for.body, %if.then1158  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 11159  %lftr.wideiv = trunc i64 %indvars.iv.next to i321160  %exitcond = icmp eq i32 %lftr.wideiv, %n1161  br i1 %exitcond, label %for.end, label %for.body1162 1163for.end:                                          ; preds = %for.inc, %entry1164  ret void1165}1166 1167declare void @use(i64)1168 1169define void @licm_deref_no_hoist(i1 %c1, i1 %c2, ptr align 8 dereferenceable(8) %p1) {1170; CHECK-LABEL: @licm_deref_no_hoist(1171; CHECK-NEXT:  entry:1172; CHECK-NEXT:    [[P2:%.*]] = load ptr, ptr [[P1:%.*]], align 8, !align [[META1:![0-9]+]]1173; CHECK-NEXT:    br label [[LOOP:%.*]]1174; CHECK:       loop:1175; CHECK-NEXT:    br i1 [[C1:%.*]], label [[IF:%.*]], label [[LOOP_LATCH:%.*]]1176; CHECK:       if:1177; CHECK-NEXT:    [[V:%.*]] = load i64, ptr [[P2]], align 81178; CHECK-NEXT:    call void @use(i64 [[V]]) #[[ATTR1:[0-9]+]]1179; CHECK-NEXT:    br label [[LOOP_LATCH]]1180; CHECK:       loop.latch:1181; CHECK-NEXT:    br i1 [[C2:%.*]], label [[LOOP]], label [[EXIT:%.*]]1182; CHECK:       exit:1183; CHECK-NEXT:    ret void1184;1185entry:1186  br label %loop1187 1188loop:1189  br i1 %c1, label %if, label %loop.latch1190 1191if:1192  %p2 = load ptr, ptr %p1, align 8, !dereferenceable !1, !align !11193  %v = load i64, ptr %p2, align 81194  call void @use(i64 %v) memory(none)1195  br label %loop.latch1196 1197loop.latch:1198  br i1 %c2, label %loop, label %exit1199 1200exit:1201  ret void1202}1203 1204define void @licm_deref_hoist(i1 %c1, i1 %c2, ptr align 8 dereferenceable(8) %p1) {1205; CHECK-LABEL: @licm_deref_hoist(1206; CHECK-NEXT:  entry:1207; CHECK-NEXT:    [[P2:%.*]] = load ptr, ptr [[P1:%.*]], align 8, !dereferenceable [[META1]], !align [[META1]]1208; CHECK-NEXT:    [[V:%.*]] = load i64, ptr [[P2]], align 81209; CHECK-NEXT:    br label [[LOOP:%.*]]1210; CHECK:       loop:1211; CHECK-NEXT:    br i1 [[C1:%.*]], label [[IF:%.*]], label [[LOOP_LATCH:%.*]]1212; CHECK:       if:1213; CHECK-NEXT:    call void @use(i64 [[V]]) #[[ATTR1]]1214; CHECK-NEXT:    br label [[LOOP_LATCH]]1215; CHECK:       loop.latch:1216; CHECK-NEXT:    br i1 [[C2:%.*]], label [[LOOP]], label [[EXIT:%.*]]1217; CHECK:       exit:1218; CHECK-NEXT:    ret void1219;1220entry:1221  %p2 = load ptr, ptr %p1, align 8, !dereferenceable !1, !align !11222  br label %loop1223 1224loop:1225  br i1 %c1, label %if, label %loop.latch1226 1227if:1228  %v = load i64, ptr %p2, align 81229  call void @use(i64 %v) memory(none)1230  br label %loop.latch1231 1232loop.latch:1233  br i1 %c2, label %loop, label %exit1234 1235exit:1236  ret void1237}1238 1239attributes #0 = { nounwind uwtable nofree nosync }1240!0 = !{i64 4}1241!1 = !{i64 8}1242