Skip to content

Instantly share code, notes, and snippets.

@nikic

nikic/.ll Secret

Created June 19, 2021 18:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikic/0541f7937f6db4867ef7fd4d7673a2b1 to your computer and use it in GitHub Desktop.
Save nikic/0541f7937f6db4867ef7fd4d7673a2b1 to your computer and use it in GitHub Desktop.
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -loop-unroll -unroll-allow-partial -unroll-runtime-multi-exit < %s | FileCheck %s
; This loop has a known trip count on the non-latch exit. When performing
; runtime unrolling (at least when using a prologue rather than epilogue) we
; should not fold that exit based on known trip count information prior to
; prologue insertion, as that may change the trip count for the modified loop.
define void @test(i32 %s, i32 %n) {
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[N2:%.*]] = add i32 [[S:%.*]], 123
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[S]], [[ENTRY:%.*]] ], [ [[I_INC_30:%.*]], [[LATCH_30:%.*]] ]
; CHECK-NEXT: br label [[LATCH:%.*]]
; CHECK: latch:
; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[I]], [[N:%.*]]
; CHECK-NEXT: [[I_INC:%.*]] = add i32 [[I]], 1
; CHECK-NEXT: br i1 [[C2]], label [[EXIT2:%.*]], label [[LOOP_1:%.*]]
; CHECK: exit1:
; CHECK-NEXT: ret void
; CHECK: exit2:
; CHECK-NEXT: ret void
; CHECK: loop.1:
; CHECK-NEXT: br label [[LATCH_1:%.*]]
; CHECK: latch.1:
; CHECK-NEXT: [[C2_1:%.*]] = icmp eq i32 [[I_INC]], [[N]]
; CHECK-NEXT: [[I_INC_1:%.*]] = add i32 [[I_INC]], 1
; CHECK-NEXT: br i1 [[C2_1]], label [[EXIT2]], label [[LOOP_2:%.*]]
; CHECK: loop.2:
; CHECK-NEXT: br label [[LATCH_2:%.*]]
; CHECK: latch.2:
; CHECK-NEXT: [[C2_2:%.*]] = icmp eq i32 [[I_INC_1]], [[N]]
; CHECK-NEXT: [[I_INC_2:%.*]] = add i32 [[I_INC_1]], 1
; CHECK-NEXT: br i1 [[C2_2]], label [[EXIT2]], label [[LOOP_3:%.*]]
; CHECK: loop.3:
; CHECK-NEXT: br label [[LATCH_3:%.*]]
; CHECK: latch.3:
; CHECK-NEXT: [[C2_3:%.*]] = icmp eq i32 [[I_INC_2]], [[N]]
; CHECK-NEXT: [[I_INC_3:%.*]] = add i32 [[I_INC_2]], 1
; CHECK-NEXT: br i1 [[C2_3]], label [[EXIT2]], label [[LOOP_4:%.*]]
; CHECK: loop.4:
; CHECK-NEXT: br label [[LATCH_4:%.*]]
; CHECK: latch.4:
; CHECK-NEXT: [[C2_4:%.*]] = icmp eq i32 [[I_INC_3]], [[N]]
; CHECK-NEXT: [[I_INC_4:%.*]] = add i32 [[I_INC_3]], 1
; CHECK-NEXT: br i1 [[C2_4]], label [[EXIT2]], label [[LOOP_5:%.*]]
; CHECK: loop.5:
; CHECK-NEXT: br label [[LATCH_5:%.*]]
; CHECK: latch.5:
; CHECK-NEXT: [[C2_5:%.*]] = icmp eq i32 [[I_INC_4]], [[N]]
; CHECK-NEXT: [[I_INC_5:%.*]] = add i32 [[I_INC_4]], 1
; CHECK-NEXT: br i1 [[C2_5]], label [[EXIT2]], label [[LOOP_6:%.*]]
; CHECK: loop.6:
; CHECK-NEXT: br label [[LATCH_6:%.*]]
; CHECK: latch.6:
; CHECK-NEXT: [[C2_6:%.*]] = icmp eq i32 [[I_INC_5]], [[N]]
; CHECK-NEXT: [[I_INC_6:%.*]] = add i32 [[I_INC_5]], 1
; CHECK-NEXT: br i1 [[C2_6]], label [[EXIT2]], label [[LOOP_7:%.*]]
; CHECK: loop.7:
; CHECK-NEXT: br label [[LATCH_7:%.*]]
; CHECK: latch.7:
; CHECK-NEXT: [[C2_7:%.*]] = icmp eq i32 [[I_INC_6]], [[N]]
; CHECK-NEXT: [[I_INC_7:%.*]] = add i32 [[I_INC_6]], 1
; CHECK-NEXT: br i1 [[C2_7]], label [[EXIT2]], label [[LOOP_8:%.*]]
; CHECK: loop.8:
; CHECK-NEXT: br label [[LATCH_8:%.*]]
; CHECK: latch.8:
; CHECK-NEXT: [[C2_8:%.*]] = icmp eq i32 [[I_INC_7]], [[N]]
; CHECK-NEXT: [[I_INC_8:%.*]] = add i32 [[I_INC_7]], 1
; CHECK-NEXT: br i1 [[C2_8]], label [[EXIT2]], label [[LOOP_9:%.*]]
; CHECK: loop.9:
; CHECK-NEXT: br label [[LATCH_9:%.*]]
; CHECK: latch.9:
; CHECK-NEXT: [[C2_9:%.*]] = icmp eq i32 [[I_INC_8]], [[N]]
; CHECK-NEXT: [[I_INC_9:%.*]] = add i32 [[I_INC_8]], 1
; CHECK-NEXT: br i1 [[C2_9]], label [[EXIT2]], label [[LOOP_10:%.*]]
; CHECK: loop.10:
; CHECK-NEXT: br label [[LATCH_10:%.*]]
; CHECK: latch.10:
; CHECK-NEXT: [[C2_10:%.*]] = icmp eq i32 [[I_INC_9]], [[N]]
; CHECK-NEXT: [[I_INC_10:%.*]] = add i32 [[I_INC_9]], 1
; CHECK-NEXT: br i1 [[C2_10]], label [[EXIT2]], label [[LOOP_11:%.*]]
; CHECK: loop.11:
; CHECK-NEXT: br label [[LATCH_11:%.*]]
; CHECK: latch.11:
; CHECK-NEXT: [[C2_11:%.*]] = icmp eq i32 [[I_INC_10]], [[N]]
; CHECK-NEXT: [[I_INC_11:%.*]] = add i32 [[I_INC_10]], 1
; CHECK-NEXT: br i1 [[C2_11]], label [[EXIT2]], label [[LOOP_12:%.*]]
; CHECK: loop.12:
; CHECK-NEXT: br label [[LATCH_12:%.*]]
; CHECK: latch.12:
; CHECK-NEXT: [[C2_12:%.*]] = icmp eq i32 [[I_INC_11]], [[N]]
; CHECK-NEXT: [[I_INC_12:%.*]] = add i32 [[I_INC_11]], 1
; CHECK-NEXT: br i1 [[C2_12]], label [[EXIT2]], label [[LOOP_13:%.*]]
; CHECK: loop.13:
; CHECK-NEXT: br label [[LATCH_13:%.*]]
; CHECK: latch.13:
; CHECK-NEXT: [[C2_13:%.*]] = icmp eq i32 [[I_INC_12]], [[N]]
; CHECK-NEXT: [[I_INC_13:%.*]] = add i32 [[I_INC_12]], 1
; CHECK-NEXT: br i1 [[C2_13]], label [[EXIT2]], label [[LOOP_14:%.*]]
; CHECK: loop.14:
; CHECK-NEXT: br label [[LATCH_14:%.*]]
; CHECK: latch.14:
; CHECK-NEXT: [[C2_14:%.*]] = icmp eq i32 [[I_INC_13]], [[N]]
; CHECK-NEXT: [[I_INC_14:%.*]] = add i32 [[I_INC_13]], 1
; CHECK-NEXT: br i1 [[C2_14]], label [[EXIT2]], label [[LOOP_15:%.*]]
; CHECK: loop.15:
; CHECK-NEXT: br label [[LATCH_15:%.*]]
; CHECK: latch.15:
; CHECK-NEXT: [[C2_15:%.*]] = icmp eq i32 [[I_INC_14]], [[N]]
; CHECK-NEXT: [[I_INC_15:%.*]] = add i32 [[I_INC_14]], 1
; CHECK-NEXT: br i1 [[C2_15]], label [[EXIT2]], label [[LOOP_16:%.*]]
; CHECK: loop.16:
; CHECK-NEXT: br label [[LATCH_16:%.*]]
; CHECK: latch.16:
; CHECK-NEXT: [[C2_16:%.*]] = icmp eq i32 [[I_INC_15]], [[N]]
; CHECK-NEXT: [[I_INC_16:%.*]] = add i32 [[I_INC_15]], 1
; CHECK-NEXT: br i1 [[C2_16]], label [[EXIT2]], label [[LOOP_17:%.*]]
; CHECK: loop.17:
; CHECK-NEXT: br label [[LATCH_17:%.*]]
; CHECK: latch.17:
; CHECK-NEXT: [[C2_17:%.*]] = icmp eq i32 [[I_INC_16]], [[N]]
; CHECK-NEXT: [[I_INC_17:%.*]] = add i32 [[I_INC_16]], 1
; CHECK-NEXT: br i1 [[C2_17]], label [[EXIT2]], label [[LOOP_18:%.*]]
; CHECK: loop.18:
; CHECK-NEXT: br label [[LATCH_18:%.*]]
; CHECK: latch.18:
; CHECK-NEXT: [[C2_18:%.*]] = icmp eq i32 [[I_INC_17]], [[N]]
; CHECK-NEXT: [[I_INC_18:%.*]] = add i32 [[I_INC_17]], 1
; CHECK-NEXT: br i1 [[C2_18]], label [[EXIT2]], label [[LOOP_19:%.*]]
; CHECK: loop.19:
; CHECK-NEXT: br label [[LATCH_19:%.*]]
; CHECK: latch.19:
; CHECK-NEXT: [[C2_19:%.*]] = icmp eq i32 [[I_INC_18]], [[N]]
; CHECK-NEXT: [[I_INC_19:%.*]] = add i32 [[I_INC_18]], 1
; CHECK-NEXT: br i1 [[C2_19]], label [[EXIT2]], label [[LOOP_20:%.*]]
; CHECK: loop.20:
; CHECK-NEXT: br label [[LATCH_20:%.*]]
; CHECK: latch.20:
; CHECK-NEXT: [[C2_20:%.*]] = icmp eq i32 [[I_INC_19]], [[N]]
; CHECK-NEXT: [[I_INC_20:%.*]] = add i32 [[I_INC_19]], 1
; CHECK-NEXT: br i1 [[C2_20]], label [[EXIT2]], label [[LOOP_21:%.*]]
; CHECK: loop.21:
; CHECK-NEXT: br label [[LATCH_21:%.*]]
; CHECK: latch.21:
; CHECK-NEXT: [[C2_21:%.*]] = icmp eq i32 [[I_INC_20]], [[N]]
; CHECK-NEXT: [[I_INC_21:%.*]] = add i32 [[I_INC_20]], 1
; CHECK-NEXT: br i1 [[C2_21]], label [[EXIT2]], label [[LOOP_22:%.*]]
; CHECK: loop.22:
; CHECK-NEXT: br label [[LATCH_22:%.*]]
; CHECK: latch.22:
; CHECK-NEXT: [[C2_22:%.*]] = icmp eq i32 [[I_INC_21]], [[N]]
; CHECK-NEXT: [[I_INC_22:%.*]] = add i32 [[I_INC_21]], 1
; CHECK-NEXT: br i1 [[C2_22]], label [[EXIT2]], label [[LOOP_23:%.*]]
; CHECK: loop.23:
; CHECK-NEXT: br label [[LATCH_23:%.*]]
; CHECK: latch.23:
; CHECK-NEXT: [[C2_23:%.*]] = icmp eq i32 [[I_INC_22]], [[N]]
; CHECK-NEXT: [[I_INC_23:%.*]] = add i32 [[I_INC_22]], 1
; CHECK-NEXT: br i1 [[C2_23]], label [[EXIT2]], label [[LOOP_24:%.*]]
; CHECK: loop.24:
; CHECK-NEXT: br label [[LATCH_24:%.*]]
; CHECK: latch.24:
; CHECK-NEXT: [[C2_24:%.*]] = icmp eq i32 [[I_INC_23]], [[N]]
; CHECK-NEXT: [[I_INC_24:%.*]] = add i32 [[I_INC_23]], 1
; CHECK-NEXT: br i1 [[C2_24]], label [[EXIT2]], label [[LOOP_25:%.*]]
; CHECK: loop.25:
; CHECK-NEXT: br label [[LATCH_25:%.*]]
; CHECK: latch.25:
; CHECK-NEXT: [[C2_25:%.*]] = icmp eq i32 [[I_INC_24]], [[N]]
; CHECK-NEXT: [[I_INC_25:%.*]] = add i32 [[I_INC_24]], 1
; CHECK-NEXT: br i1 [[C2_25]], label [[EXIT2]], label [[LOOP_26:%.*]]
; CHECK: loop.26:
; CHECK-NEXT: br label [[LATCH_26:%.*]]
; CHECK: latch.26:
; CHECK-NEXT: [[C2_26:%.*]] = icmp eq i32 [[I_INC_25]], [[N]]
; CHECK-NEXT: [[I_INC_26:%.*]] = add i32 [[I_INC_25]], 1
; CHECK-NEXT: br i1 [[C2_26]], label [[EXIT2]], label [[LOOP_27:%.*]]
; CHECK: loop.27:
; CHECK-NEXT: br label [[LATCH_27:%.*]]
; CHECK: latch.27:
; CHECK-NEXT: [[C2_27:%.*]] = icmp eq i32 [[I_INC_26]], [[N]]
; CHECK-NEXT: [[I_INC_27:%.*]] = add i32 [[I_INC_26]], 1
; CHECK-NEXT: br i1 [[C2_27]], label [[EXIT2]], label [[LOOP_28:%.*]]
; CHECK: loop.28:
; CHECK-NEXT: br label [[LATCH_28:%.*]]
; CHECK: latch.28:
; CHECK-NEXT: [[C2_28:%.*]] = icmp eq i32 [[I_INC_27]], [[N]]
; CHECK-NEXT: [[I_INC_28:%.*]] = add i32 [[I_INC_27]], 1
; CHECK-NEXT: br i1 [[C2_28]], label [[EXIT2]], label [[LOOP_29:%.*]]
; CHECK: loop.29:
; CHECK-NEXT: br label [[LATCH_29:%.*]]
; CHECK: latch.29:
; CHECK-NEXT: [[C2_29:%.*]] = icmp eq i32 [[I_INC_28]], [[N]]
; CHECK-NEXT: [[I_INC_29:%.*]] = add i32 [[I_INC_28]], 1
; CHECK-NEXT: br i1 [[C2_29]], label [[EXIT2]], label [[LOOP_30:%.*]]
; CHECK: loop.30:
; CHECK-NEXT: [[C1_30:%.*]] = icmp eq i32 [[I_INC_29]], [[N2]]
; CHECK-NEXT: br i1 [[C1_30]], label [[EXIT1:%.*]], label [[LATCH_30]]
; CHECK: latch.30:
; CHECK-NEXT: [[C2_30:%.*]] = icmp eq i32 [[I_INC_29]], [[N]]
; CHECK-NEXT: [[I_INC_30]] = add i32 [[I_INC_29]], 1
; CHECK-NEXT: br i1 [[C2_30]], label [[EXIT2]], label [[LOOP]]
;
entry:
%n2 = add i32 %s, 123
br label %loop
loop:
%i = phi i32 [ %s, %entry], [ %i.inc, %latch ]
%c1 = icmp eq i32 %i, %n2
br i1 %c1, label %exit1, label %latch
latch:
%c2 = icmp eq i32 %i, %n
%i.inc = add i32 %i, 1
br i1 %c2, label %exit2, label %loop
exit1:
ret void
exit2:
ret void
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment