xref: /llvm-project/llvm/test/Transforms/CodeGenPrepare/X86/bitreverse-hang.ll (revision d9e51e75521d5e33f24a6c1afacae5dbc115f96d)
15a56a25bSFangrui Song; RUN: opt < %s -loop-unroll -codegenprepare -S -mtriple=x86_64 | FileCheck %s
25a56a25bSFangrui Song
35a56a25bSFangrui Song; This test is a worst-case scenario for bitreversal/byteswap detection.
45a56a25bSFangrui Song; After loop unrolling (the unrolled loop is unreadably large so it has been kept
55a56a25bSFangrui Song; rolled here), we have a binary tree of OR operands (as bitreversal detection
65a56a25bSFangrui Song; looks straight through shifts):
75a56a25bSFangrui Song;
85a56a25bSFangrui Song;  OR
95a56a25bSFangrui Song;  | \
105a56a25bSFangrui Song;  |  LSHR
115a56a25bSFangrui Song;  | /
125a56a25bSFangrui Song;  OR
135a56a25bSFangrui Song;  | \
145a56a25bSFangrui Song;  |  LSHR
155a56a25bSFangrui Song;  | /
165a56a25bSFangrui Song;  OR
175a56a25bSFangrui Song;
185a56a25bSFangrui Song; This results in exponential runtime. The loop here is 32 iterations which will
195a56a25bSFangrui Song; totally hang if we don't deal with this case cleverly.
205a56a25bSFangrui Song
215a56a25bSFangrui Song@b = common global i32 0, align 4
225a56a25bSFangrui Song
235a56a25bSFangrui Song; CHECK: define i32 @fn1
245a56a25bSFangrui Songdefine i32 @fn1() #0 {
255a56a25bSFangrui Songentry:
26*d9e51e75SMatt Arsenault  %b.promoted = load i32, ptr @b, align 4, !tbaa !2
275a56a25bSFangrui Song  br label %for.body
285a56a25bSFangrui Song
295a56a25bSFangrui Songfor.body:                                         ; preds = %for.body, %entry
305a56a25bSFangrui Song  %or4 = phi i32 [ %b.promoted, %entry ], [ %or, %for.body ]
315a56a25bSFangrui Song  %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
325a56a25bSFangrui Song  %shr = lshr i32 %or4, 1
335a56a25bSFangrui Song  %or = or i32 %shr, %or4
345a56a25bSFangrui Song  %inc = add nuw nsw i32 %i.03, 1
355a56a25bSFangrui Song  %exitcond = icmp eq i32 %inc, 32
365a56a25bSFangrui Song  br i1 %exitcond, label %for.end, label %for.body
375a56a25bSFangrui Song
385a56a25bSFangrui Songfor.end:                                          ; preds = %for.body
39*d9e51e75SMatt Arsenault  store i32 %or, ptr @b, align 4, !tbaa !2
405a56a25bSFangrui Song  ret i32 undef
415a56a25bSFangrui Song}
425a56a25bSFangrui Song
434ab3041aSserge-sans-pailleattributes #0 = { norecurse nounwind ssp uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="core2" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }
445a56a25bSFangrui Song
455a56a25bSFangrui Song!llvm.module.flags = !{!0}
465a56a25bSFangrui Song!llvm.ident = !{!1}
475a56a25bSFangrui Song
485a56a25bSFangrui Song!0 = !{i32 1, !"PIC Level", i32 2}
495a56a25bSFangrui Song!1 = !{!"clang version 3.8.0"}
505a56a25bSFangrui Song!2 = !{!3, !3, i64 0}
515a56a25bSFangrui Song!3 = !{!"int", !4, i64 0}
525a56a25bSFangrui Song!4 = !{!"omnipotent char", !5, i64 0}
535a56a25bSFangrui Song!5 = !{!"Simple C/C++ TBAA"}
54