1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine --instcombine-max-iterations=0 -S | FileCheck %s --check-prefix=ZERO
3; RUN: opt < %s -instcombine --instcombine-max-iterations=1 -S | FileCheck %s --check-prefix=ONE
4; RUN: opt < %s -instcombine -S | FileCheck %s --check-prefix=FIXPOINT
5; RUN: not --crash opt < %s -instcombine -S --instcombine-infinite-loop-threshold=2 2>&1 | FileCheck %s --check-prefix=LOOP
6
7; Based on builtin-dynamic-object-size.ll. This requires multiple iterations of
8; InstCombine to reach a fixpoint.
9
10define i64 @weird_identity_but_ok(i64 %sz) {
11; ZERO-LABEL: @weird_identity_but_ok(
12; ZERO-NEXT:  entry:
13; ZERO-NEXT:    [[CALL:%.*]] = tail call i8* @malloc(i64 [[SZ:%.*]])
14; ZERO-NEXT:    [[CALC_SIZE:%.*]] = tail call i64 @llvm.objectsize.i64.p0i8(i8* [[CALL]], i1 false, i1 true, i1 true)
15; ZERO-NEXT:    tail call void @free(i8* [[CALL]])
16; ZERO-NEXT:    ret i64 [[CALC_SIZE]]
17;
18; ONE-LABEL: @weird_identity_but_ok(
19; ONE-NEXT:  entry:
20; ONE-NEXT:    [[TMP0:%.*]] = sub i64 [[SZ:%.*]], 0
21; ONE-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[SZ]], 0
22; ONE-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP0]]
23; ONE-NEXT:    ret i64 [[TMP2]]
24;
25; FIXPOINT-LABEL: @weird_identity_but_ok(
26; FIXPOINT-NEXT:  entry:
27; FIXPOINT-NEXT:    ret i64 [[SZ:%.*]]
28;
29; LOOP: LLVM ERROR: Instruction Combining seems stuck in an infinite loop after 2 iterations.
30entry:
31  %call = tail call i8* @malloc(i64 %sz)
32  %calc_size = tail call i64 @llvm.objectsize.i64.p0i8(i8* %call, i1 false, i1 true, i1 true)
33  tail call void @free(i8* %call)
34  ret i64 %calc_size
35}
36
37declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1)
38declare i8* @malloc(i64)
39declare void @free(i8*)
40