1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -passes=newgvn -S < %s | FileCheck %s 3 4; C source: 5; 6; void f(int x) { 7; if (x != 1) 8; puts (x == 2 ? "a" : "b"); 9; for (;;) { 10; puts("step 1"); 11; if (x == 2) 12; continue; 13; printf("step 2: %d\n", x); 14; } 15; } 16; 17; If we PRE %cmp3, CodeGenPrepare won't be able to sink the compare down to its 18; uses, and we are forced to keep both %x and %cmp3 in registers in the loop. 19; 20; It is just as cheap to recompute the icmp against %x as it is to compare a 21; GPR against 0. On x86-64, the br i1 %cmp3 becomes: 22; 23; testb %r12b, %r12b 24; jne LBB0_3 25; 26; The sunk icmp is: 27; 28; cmpl $2, %ebx 29; je LBB0_3 30; 31; This is just as good, and it doesn't require a separate register. 32; 33; CHECK-NOT: phi i1 34 35@.str = private unnamed_addr constant [2 x i8] c"a\00", align 1 36@.str1 = private unnamed_addr constant [2 x i8] c"b\00", align 1 37@.str2 = private unnamed_addr constant [7 x i8] c"step 1\00", align 1 38@.str3 = private unnamed_addr constant [12 x i8] c"step 2: %d\0A\00", align 1 39 40define void @f(i32 %x) noreturn nounwind uwtable ssp { 41; CHECK-LABEL: define void @f( 42; CHECK-SAME: i32 [[X:%.*]]) #[[ATTR0:[0-9]+]] { 43; CHECK-NEXT: entry: 44; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 1 45; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND_PREHEADER:%.*]], label [[IF_THEN:%.*]] 46; CHECK: if.then: 47; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], 2 48; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP1]], ptr @.str, ptr @.str1 49; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @puts(ptr [[COND]]) #[[ATTR1:[0-9]+]] 50; CHECK-NEXT: br label [[FOR_COND_PREHEADER]] 51; CHECK: for.cond.preheader: 52; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[X]], 2 53; CHECK-NEXT: br label [[FOR_COND:%.*]] 54; CHECK: for.cond: 55; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @puts(ptr @.str2) #[[ATTR1]] 56; CHECK-NEXT: br i1 [[CMP3]], label [[FOR_COND_BACKEDGE:%.*]], label [[IF_END5:%.*]] 57; CHECK: if.end5: 58; CHECK-NEXT: [[CALL6:%.*]] = tail call i32 (ptr, ...) @printf(ptr @.str3, i32 [[X]]) #[[ATTR1]] 59; CHECK-NEXT: br label [[FOR_COND_BACKEDGE]] 60; CHECK: for.cond.backedge: 61; CHECK-NEXT: br label [[FOR_COND]] 62; 63entry: 64 %cmp = icmp eq i32 %x, 1 65 br i1 %cmp, label %for.cond.preheader, label %if.then 66 67if.then: ; preds = %entry 68 %cmp1 = icmp eq i32 %x, 2 69 %cond = select i1 %cmp1, ptr @.str, ptr @.str1 70 %call = tail call i32 @puts(ptr %cond) nounwind 71 br label %for.cond.preheader 72 73for.cond.preheader: ; preds = %entry, %if.then 74 %cmp3 = icmp eq i32 %x, 2 75 br label %for.cond 76 77for.cond: ; preds = %for.cond.backedge, %for.cond.preheader 78 %call2 = tail call i32 @puts(ptr @.str2) nounwind 79 br i1 %cmp3, label %for.cond.backedge, label %if.end5 80 81if.end5: ; preds = %for.cond 82 %call6 = tail call i32 (ptr, ...) @printf(ptr @.str3, i32 %x) nounwind 83 br label %for.cond.backedge 84 85for.cond.backedge: ; preds = %if.end5, %for.cond 86 br label %for.cond 87} 88 89declare i32 @puts(ptr nocapture) nounwind 90 91declare i32 @printf(ptr nocapture, ...) nounwind 92