xref: /aosp_15_r20/external/llvm/test/Transforms/GVN/pre-compare.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -gvn -S < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker; C source:
4*9880d681SAndroid Build Coastguard Worker;
5*9880d681SAndroid Build Coastguard Worker;   void f(int x) {
6*9880d681SAndroid Build Coastguard Worker;     if (x != 1)
7*9880d681SAndroid Build Coastguard Worker;       puts (x == 2 ? "a" : "b");
8*9880d681SAndroid Build Coastguard Worker;     for (;;) {
9*9880d681SAndroid Build Coastguard Worker;       puts("step 1");
10*9880d681SAndroid Build Coastguard Worker;       if (x == 2)
11*9880d681SAndroid Build Coastguard Worker;         continue;
12*9880d681SAndroid Build Coastguard Worker;       printf("step 2: %d\n", x);
13*9880d681SAndroid Build Coastguard Worker;     }
14*9880d681SAndroid Build Coastguard Worker;   }
15*9880d681SAndroid Build Coastguard Worker;
16*9880d681SAndroid Build Coastguard Worker; If we PRE %cmp3, CodeGenPrepare won't be able to sink the compare down to its
17*9880d681SAndroid Build Coastguard Worker; uses, and we are forced to keep both %x and %cmp3 in registers in the loop.
18*9880d681SAndroid Build Coastguard Worker;
19*9880d681SAndroid Build Coastguard Worker; It is just as cheap to recompute the icmp against %x as it is to compare a
20*9880d681SAndroid Build Coastguard Worker; GPR against 0. On x86-64, the br i1 %cmp3 becomes:
21*9880d681SAndroid Build Coastguard Worker;
22*9880d681SAndroid Build Coastguard Worker;   testb %r12b, %r12b
23*9880d681SAndroid Build Coastguard Worker;   jne	LBB0_3
24*9880d681SAndroid Build Coastguard Worker;
25*9880d681SAndroid Build Coastguard Worker; The sunk icmp is:
26*9880d681SAndroid Build Coastguard Worker;
27*9880d681SAndroid Build Coastguard Worker;   cmpl $2, %ebx
28*9880d681SAndroid Build Coastguard Worker;   je	LBB0_3
29*9880d681SAndroid Build Coastguard Worker;
30*9880d681SAndroid Build Coastguard Worker; This is just as good, and it doesn't require a separate register.
31*9880d681SAndroid Build Coastguard Worker;
32*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi i1
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker@.str = private unnamed_addr constant [2 x i8] c"a\00", align 1
35*9880d681SAndroid Build Coastguard Worker@.str1 = private unnamed_addr constant [2 x i8] c"b\00", align 1
36*9880d681SAndroid Build Coastguard Worker@.str2 = private unnamed_addr constant [7 x i8] c"step 1\00", align 1
37*9880d681SAndroid Build Coastguard Worker@.str3 = private unnamed_addr constant [12 x i8] c"step 2: %d\0A\00", align 1
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Workerdefine void @f(i32 %x) noreturn nounwind uwtable ssp {
40*9880d681SAndroid Build Coastguard Workerentry:
41*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %x, 1
42*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %for.cond.preheader, label %if.then
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry
45*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp eq i32 %x, 2
46*9880d681SAndroid Build Coastguard Worker  %cond = select i1 %cmp1, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str1, i64 0, i64 0)
47*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 @puts(i8* %cond) nounwind
48*9880d681SAndroid Build Coastguard Worker  br label %for.cond.preheader
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Workerfor.cond.preheader:                               ; preds = %entry, %if.then
51*9880d681SAndroid Build Coastguard Worker  %cmp3 = icmp eq i32 %x, 2
52*9880d681SAndroid Build Coastguard Worker  br label %for.cond
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Workerfor.cond:                                         ; preds = %for.cond.backedge, %for.cond.preheader
55*9880d681SAndroid Build Coastguard Worker  %call2 = tail call i32 @puts(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str2, i64 0, i64 0)) nounwind
56*9880d681SAndroid Build Coastguard Worker  br i1 %cmp3, label %for.cond.backedge, label %if.end5
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Workerif.end5:                                          ; preds = %for.cond
59*9880d681SAndroid Build Coastguard Worker  %call6 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str3, i64 0, i64 0), i32 %x) nounwind
60*9880d681SAndroid Build Coastguard Worker  br label %for.cond.backedge
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Workerfor.cond.backedge:                                ; preds = %if.end5, %for.cond
63*9880d681SAndroid Build Coastguard Worker  br label %for.cond
64*9880d681SAndroid Build Coastguard Worker}
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Workerdeclare i32 @puts(i8* nocapture) nounwind
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Workerdeclare i32 @printf(i8* nocapture, ...) nounwind
69