1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instsimplify -S | FileCheck %s 3 4declare void @llvm.assume(i1) 5declare void @use(i1) 6 7define void @basic_ugt(i32 %x, i32 %y) { 8; CHECK-LABEL: @basic_ugt( 9; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] 10; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 11; CHECK-NEXT: call void @use(i1 true) 12; CHECK-NEXT: call void @use(i1 true) 13; CHECK-NEXT: call void @use(i1 false) 14; CHECK-NEXT: call void @use(i1 false) 15; CHECK-NEXT: call void @use(i1 false) 16; CHECK-NEXT: call void @use(i1 false) 17; CHECK-NEXT: call void @use(i1 true) 18; CHECK-NEXT: call void @use(i1 true) 19; CHECK-NEXT: ret void 20; 21 %cmp1 = icmp ugt i32 %x, %y 22 call void @llvm.assume(i1 %cmp1) 23 24 %cmp2 = icmp ugt i32 %x, %y 25 call void @use(i1 %cmp2) 26 %cmp3 = icmp uge i32 %x, %y 27 call void @use(i1 %cmp3) 28 %cmp4 = icmp ult i32 %x, %y 29 call void @use(i1 %cmp4) 30 %cmp5 = icmp ule i32 %x, %y 31 call void @use(i1 %cmp5) 32 33 %cmp6 = icmp ugt i32 %y, %x 34 call void @use(i1 %cmp6) 35 %cmp7 = icmp uge i32 %y, %x 36 call void @use(i1 %cmp7) 37 %cmp8 = icmp ult i32 %y, %x 38 call void @use(i1 %cmp8) 39 %cmp9 = icmp ule i32 %y, %x 40 call void @use(i1 %cmp9) 41 42 ret void 43} 44 45define void @basic_uge(i32 %x, i32 %y) { 46; CHECK-LABEL: @basic_uge( 47; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]] 48; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 49; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], [[Y]] 50; CHECK-NEXT: call void @use(i1 [[CMP2]]) 51; CHECK-NEXT: call void @use(i1 true) 52; CHECK-NEXT: call void @use(i1 false) 53; CHECK-NEXT: [[CMP5:%.*]] = icmp ule i32 [[X]], [[Y]] 54; CHECK-NEXT: call void @use(i1 [[CMP5]]) 55; CHECK-NEXT: call void @use(i1 false) 56; CHECK-NEXT: [[CMP7:%.*]] = icmp uge i32 [[Y]], [[X]] 57; CHECK-NEXT: call void @use(i1 [[CMP7]]) 58; CHECK-NEXT: [[CMP8:%.*]] = icmp ult i32 [[Y]], [[X]] 59; CHECK-NEXT: call void @use(i1 [[CMP8]]) 60; CHECK-NEXT: call void @use(i1 true) 61; CHECK-NEXT: ret void 62; 63 %cmp1 = icmp uge i32 %x, %y 64 call void @llvm.assume(i1 %cmp1) 65 66 %cmp2 = icmp ugt i32 %x, %y 67 call void @use(i1 %cmp2) 68 %cmp3 = icmp uge i32 %x, %y 69 call void @use(i1 %cmp3) 70 %cmp4 = icmp ult i32 %x, %y 71 call void @use(i1 %cmp4) 72 %cmp5 = icmp ule i32 %x, %y 73 call void @use(i1 %cmp5) 74 75 %cmp6 = icmp ugt i32 %y, %x 76 call void @use(i1 %cmp6) 77 %cmp7 = icmp uge i32 %y, %x 78 call void @use(i1 %cmp7) 79 %cmp8 = icmp ult i32 %y, %x 80 call void @use(i1 %cmp8) 81 %cmp9 = icmp ule i32 %y, %x 82 call void @use(i1 %cmp9) 83 84 ret void 85} 86 87; This does not simplify in InstSimplify, because AssumptionCache tracker 88; does not track values through "and". The "and" assume will be broken 89; down into two separate assume calls by InstCombine. 90define void @and(i32 %x, i32 %y, i32 %z) { 91; CHECK-LABEL: @and( 92; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]] 93; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y]] 94; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 95; CHECK-NEXT: call void @llvm.assume(i1 [[AND]]) 96; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[X]], [[Y]] 97; CHECK-NEXT: call void @use(i1 [[CMP3]]) 98; CHECK-NEXT: [[CMP4:%.*]] = icmp uge i32 [[X]], [[Y]] 99; CHECK-NEXT: call void @use(i1 [[CMP4]]) 100; CHECK-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[Z]], [[Y]] 101; CHECK-NEXT: call void @use(i1 [[CMP5]]) 102; CHECK-NEXT: [[CMP6:%.*]] = icmp uge i32 [[Z]], [[Y]] 103; CHECK-NEXT: call void @use(i1 [[CMP6]]) 104; CHECK-NEXT: ret void 105; 106 %cmp1 = icmp ugt i32 %x, %y 107 %cmp2 = icmp ugt i32 %z, %y 108 %and = and i1 %cmp1, %cmp2 109 call void @llvm.assume(i1 %and) 110 111 %cmp3 = icmp ugt i32 %x, %y 112 call void @use(i1 %cmp3) 113 %cmp4 = icmp uge i32 %x, %y 114 call void @use(i1 %cmp4) 115 %cmp5 = icmp ugt i32 %z, %y 116 call void @use(i1 %cmp5) 117 %cmp6 = icmp uge i32 %z, %y 118 call void @use(i1 %cmp6) 119 120 ret void 121} 122