reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -newgvn -S | FileCheck %s

@g_20 = external global i32, align 4

define void @test() {
; CHECK-LABEL: @test(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    br label [[BB1:%.*]]
; CHECK:       bb1:
; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD1:%.*]], [[CRITEDGE:%.*]] ]
; CHECK-NEXT:    store i32 [[STOREMERGE]], i32* @g_20, align 4
; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i32 [[STOREMERGE]], 0
; CHECK-NEXT:    br i1 [[CMP0]], label [[LR_PH:%.*]], label [[CRITEDGE]]
; CHECK:       lr.ph:
; CHECK-NEXT:    [[LV:%.*]] = load i64, i64* inttoptr (i64 16 to i64*), align 16
; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i64 [[LV]], 0
; CHECK-NEXT:    br i1 [[CMP1]], label [[PREHEADER_SPLIT:%.*]], label [[CRITEDGE]]
; CHECK:       preheader.split:
; CHECK-NEXT:    br label [[PREHEADER_SPLIT]]
; CHECK:       critedge:
; CHECK-NEXT:    [[PHIOFOPS1:%.*]] = phi i1 [ false, [[BB1]] ], [ true, [[LR_PH]] ]
; CHECK-NEXT:    [[PHIOFOPS:%.*]] = phi i1 [ [[CMP0]], [[BB1]] ], [ true, [[LR_PH]] ]
; CHECK-NEXT:    [[DOT05_LCSSA:%.*]] = phi i32 [ 0, [[BB1]] ], [ -1, [[LR_PH]] ]
; CHECK-NEXT:    [[ADD1]] = add nsw i32 [[STOREMERGE]], -1
; CHECK-NEXT:    br i1 [[PHIOFOPS]], label [[BB1]], label [[END:%.*]]
; CHECK:       end:
; CHECK-NEXT:    ret void
;
entry:
  br label %bb1

bb1:                                      ; preds = %critedge, %entry
  %storemerge = phi i32 [ 0, %entry ], [ %add1, %critedge ]
  store i32 %storemerge, i32* @g_20, align 4
  %cmp0 = icmp eq i32 %storemerge, 0
  br i1 %cmp0, label %lr.ph, label %critedge

lr.ph:                                           ; preds = %bb1
  %lv = load i64, i64* inttoptr (i64 16 to i64*), align 16
  %cmp1 = icmp eq i64 %lv, 0
  br i1 %cmp1, label %preheader.split, label %critedge

preheader.split:                                 ; preds = %lr.ph, %preheader.split
  br label %preheader.split

critedge:                                        ; preds = %lr.ph, %bb1
  %.05.lcssa = phi i32 [ 0, %bb1 ], [ -1, %lr.ph ]
  %cmp2 = icmp ne i32 %.05.lcssa, 0
  %brmerge = or i1 %cmp0, %cmp2
  %add1 = add nsw i32 %storemerge, -1
  br i1 %brmerge, label %bb1, label %end

end:
  ret void
}

; In this test case a temporary PhiOfOps node gets moved to BB with more
; predecessors, so a new one needs to be created.
define void @test2() {
; CHECK-LABEL: @test2(
; CHECK-NEXT:    br label [[BB1:%.*]]
; CHECK:       bb1:
; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[ADD:%.*]], [[CRITEDGE:%.*]] ]
; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[STOREMERGE]], 0
; CHECK-NEXT:    br i1 [[CMP1]], label [[LR_PH:%.*]], label [[CRITEDGE]]
; CHECK:       lr.ph:
; CHECK-NEXT:    br i1 undef, label [[SPLIT1:%.*]], label [[SPLIT2:%.*]]
; CHECK:       split1:
; CHECK-NEXT:    br label [[CRITEDGE]]
; CHECK:       split2:
; CHECK-NEXT:    br label [[CRITEDGE]]
; CHECK:       critedge:
; CHECK-NEXT:    [[PHIOFOPS1:%.*]] = phi i1 [ false, [[BB1]] ], [ true, [[SPLIT2]] ], [ true, [[SPLIT1]] ]
; CHECK-NEXT:    [[PHIOFOPS:%.*]] = phi i1 [ [[CMP1]], [[BB1]] ], [ true, [[SPLIT2]] ], [ true, [[SPLIT1]] ]
; CHECK-NEXT:    [[LCSSA:%.*]] = phi i32 [ 0, [[BB1]] ], [ -1, [[SPLIT1]] ], [ -1, [[SPLIT2]] ]
; CHECK-NEXT:    [[ADD]] = add nsw i32 [[STOREMERGE]], -1
; CHECK-NEXT:    br i1 [[PHIOFOPS]], label [[BB1]], label [[EXIT:%.*]]
; CHECK:       exit:
; CHECK-NEXT:    ret void
;
  br label %bb1

bb1:                                      ; preds = %critedge, %0
  %storemerge = phi i32 [ 0, %0 ], [ %add, %critedge ]
  %cmp1 = icmp eq i32 %storemerge, 0
  br i1 %cmp1, label %lr.ph, label %critedge

lr.ph:                                           ; preds = %bb1
  br i1 undef, label %split1, label %split2

split1:                                     ; preds = %lr.ph
  br label %critedge

split2:                                     ; preds = %lr.ph
  br label %critedge

critedge:                                        ; preds = %split1, %split2, %bb1
  %lcssa = phi i32 [ 0, %bb1 ], [ -1, %split1 ], [ -1, %split2 ]
  %cmp2 = icmp ne i32 %lcssa, 0
  %brmerge = or i1 %cmp1, %cmp2
  %add = add nsw i32 %storemerge, -1
  br i1 %brmerge, label %bb1, label %exit

exit:                                      ; preds = %critedge
  ret void
}