1; RUN: opt -instcombine -value-tracking-dom-conditions=1 -S < %s | FileCheck %s 2 3target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4 5define i1 @test_cmp_ult(i64 %A) { 6; CHECK-LABEL: @test_cmp_ult 7entry: 8 %cmp = icmp ult i64 %A, 64 9 br i1 %cmp, label %taken, label %untaken 10 11taken: 12; CHECK-LABEL: taken: 13; CHECK-NEXT: ret i1 false 14 %cmp2 = icmp ugt i64 %A, 64 15 ret i1 %cmp2 16untaken: 17 ret i1 true 18} 19 20define i1 @test_cmp_ule(i64 %A) { 21; CHECK-LABEL: @test_cmp_ule 22entry: 23 %cmp = icmp ule i64 %A, 64 24 br i1 %cmp, label %taken, label %untaken 25 26taken: 27; CHECK-LABEL: taken: 28; CHECK-NEXT: ret i1 false 29 %cmp2 = icmp ugt i64 %A, 128 30 ret i1 %cmp2 31untaken: 32 ret i1 true 33} 34 35define i1 @test_cmp_sgt(i32 %A) { 36; CHECK-LABEL: @test_cmp_sgt 37entry: 38 %cmp = icmp sgt i32 %A, 10 39 br i1 %cmp, label %taken, label %untaken 40 41taken: 42; CHECK-LABEL: taken: 43; CHECK-NEXT: ret i1 true 44 %cmp2 = icmp sgt i32 %A, -1 45 ret i1 %cmp2 46untaken: 47 ret i1 true 48} 49 50define i64 @test_add_zero_bits(i64 %A) { 51; CHECK-LABEL: @test_add_zero_bits 52entry: 53 %cmp = icmp eq i64 %A, 2 54 br i1 %cmp, label %taken, label %untaken 55 56taken: 57; CHECK-LABEL: taken: 58; CHECK-NEXT: ret i64 3 59 %add = add i64 %A, 1 60 ret i64 %add 61untaken: 62 ret i64 %A 63} 64 65define i64 @test_add_nsw(i64 %A) { 66; CHECK-LABEL: @test_add_nsw 67entry: 68 %cmp = icmp ult i64 %A, 20 69 br i1 %cmp, label %taken, label %untaken 70 71taken: 72; CHECK-LABEL: taken: 73; CHECK-NEXT: %add = add nuw nsw i64 %A, 1 74; CHECK-NEXT: ret i64 %add 75 %add = add i64 %A, 1 76 ret i64 %add 77untaken: 78 ret i64 %A 79} 80 81; After sinking the instructions into the if block, check that we 82; can simplify some of them using dominating conditions. 83define i32 @test_add_zero_bits_sink(i32 %x) nounwind ssp { 84; CHECK-LABEL: @test_add_zero_bits_sink( 85; CHECK-NOT: sdiv i32 86entry: 87 %a = add nsw i32 %x, 16 88 %b = sdiv i32 %a, %x 89 %cmp = icmp ult i32 %x, 7 90 br i1 %cmp, label %bb1, label %bb2 91 92bb1: 93; CHECK-LABEL: bb1: 94; CHECK-NEXT: or i32 %x, 16 95; CHECK-NEXT: udiv i32 96 ret i32 %b 97 98bb2: 99 ret i32 %x 100} 101 102; A condition in the same block gives no information 103define i32 @test_neg1(i32 %x) nounwind ssp { 104; CHECK-LABEL: @test_neg1 105; CHECK: add 106; CHECK: sdiv 107; CHECK: icmp 108; CHECK: select 109entry: 110 %a = add nsw i32 %x, 16 111 %b = sdiv i32 %a, %x 112 %cmp = icmp ult i32 %x, 7 113 %ret = select i1 %cmp, i32 %a, i32 %b 114 ret i32 %ret 115} 116 117; A non-dominating edge gives no information 118define i32 @test_neg2(i32 %x) { 119; CHECK-LABEL: @test_neg2 120entry: 121 %cmp = icmp ult i32 %x, 7 122 br i1 %cmp, label %bb1, label %merge 123 124bb1: 125 br label %merge 126 127merge: 128; CHECK-LABEL: merge: 129; CHECK: icmp 130; CHECK: select 131 %cmp2 = icmp ult i32 %x, 7 132 %ret = select i1 %cmp2, i32 %x, i32 0 133 ret i32 %ret 134} 135 136; A unconditional branch expressed as a condition one gives no 137; information (and shouldn't trip any asserts.) 138define i32 @test_neg3(i32 %x) { 139; CHECK-LABEL: @test_neg3 140entry: 141 %cmp = icmp ult i32 %x, 7 142 br i1 %cmp, label %merge, label %merge 143merge: 144; CHECK-LABEL: merge: 145; CHECK: icmp 146; CHECK: select 147 %cmp2 = icmp ult i32 %x, 7 148 %ret = select i1 %cmp2, i32 %x, i32 0 149 ret i32 %ret 150} 151 152declare i32 @bar() 153