1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt < %s -instcombine -S | FileCheck %s 3 4 define i32 @sdiv1(i32 %x) { 5 ; CHECK-LABEL: @sdiv1( 6 ; CHECK-NEXT: [[Y:%.*]] = sdiv i32 %x, 8 7 ; CHECK-NEXT: ret i32 [[Y]] 8 ; 9 %y = sdiv i32 %x, 8 10 ret i32 %y 11 } 12 13 define i32 @sdiv2(i32 %x) { 14 ; CHECK-LABEL: @sdiv2( 15 ; CHECK-NEXT: [[Y:%.*]] = ashr exact i32 %x, 3 16 ; CHECK-NEXT: ret i32 [[Y]] 17 ; 18 %y = sdiv exact i32 %x, 8 19 ret i32 %y 20 } 21 22 define <2 x i32> @sdiv2_vec(<2 x i32> %x) { 23 ; CHECK-LABEL: @sdiv2_vec( 24 ; CHECK-NEXT: [[Y:%.*]] = ashr exact <2 x i32> %x, <i32 7, i32 7> 25 ; CHECK-NEXT: ret <2 x i32> [[Y]] 26 ; 27 %y = sdiv exact <2 x i32> %x, <i32 128, i32 128> 28 ret <2 x i32> %y 29 } 30 31 define i32 @sdiv3(i32 %x) { 32 ; CHECK-LABEL: @sdiv3( 33 ; CHECK-NEXT: [[Y:%.*]] = srem i32 %x, 3 34 ; CHECK-NEXT: [[Z:%.*]] = sub i32 %x, [[Y]] 35 ; CHECK-NEXT: ret i32 [[Z]] 36 ; 37 %y = sdiv i32 %x, 3 38 %z = mul i32 %y, 3 39 ret i32 %z 40 } 41 42 define i32 @sdiv4(i32 %x) { 43 ; CHECK-LABEL: @sdiv4( 44 ; CHECK-NEXT: ret i32 %x 45 ; 46 %y = sdiv exact i32 %x, 3 47 %z = mul i32 %y, 3 48 ret i32 %z 49 } 50 51 define i32 @sdiv5(i32 %x) { 52 ; CHECK-LABEL: @sdiv5( 53 ; CHECK-NEXT: [[Y:%.*]] = srem i32 %x, 3 54 ; CHECK-NEXT: [[Z:%.*]] = sub i32 [[Y]], %x 55 ; CHECK-NEXT: ret i32 [[Z]] 56 ; 57 %y = sdiv i32 %x, 3 58 %z = mul i32 %y, -3 59 ret i32 %z 60 } 61 62 define i32 @sdiv6(i32 %x) { 63 ; CHECK-LABEL: @sdiv6( 64 ; CHECK-NEXT: [[Z:%.*]] = sub i32 0, %x 65 ; CHECK-NEXT: ret i32 [[Z]] 66 ; 67 %y = sdiv exact i32 %x, 3 68 %z = mul i32 %y, -3 69 ret i32 %z 70 } 71 72 define i32 @udiv1(i32 %x, i32 %w) { 73 ; CHECK-LABEL: @udiv1( 74 ; CHECK-NEXT: ret i32 %x 75 ; 76 %y = udiv exact i32 %x, %w 77 %z = mul i32 %y, %w 78 ret i32 %z 79 } 80 81 define i32 @udiv2(i32 %x, i32 %w) { 82 ; CHECK-LABEL: @udiv2( 83 ; CHECK-NEXT: [[Z:%.*]] = lshr exact i32 %x, %w 84 ; CHECK-NEXT: ret i32 [[Z]] 85 ; 86 %y = shl i32 1, %w 87 %z = udiv exact i32 %x, %y 88 ret i32 %z 89 } 90 91 define i64 @ashr1(i64 %X) nounwind { 92 ; CHECK-LABEL: @ashr1( 93 ; CHECK-NEXT: [[A:%.*]] = shl i64 %X, 8 94 ; CHECK-NEXT: [[B:%.*]] = ashr exact i64 [[A]], 2 95 ; CHECK-NEXT: ret i64 [[B]] 96 ; 97 %A = shl i64 %X, 8 98 %B = ashr i64 %A, 2 ; X/4 99 ret i64 %B 100 } 101 102 ; PR9120 103 define i1 @ashr_icmp1(i64 %X) nounwind { 104 ; CHECK-LABEL: @ashr_icmp1( 105 ; CHECK-NEXT: [[B:%.*]] = icmp eq i64 %X, 0 106 ; CHECK-NEXT: ret i1 [[B]] 107 ; 108 %A = ashr exact i64 %X, 2 ; X/4 109 %B = icmp eq i64 %A, 0 110 ret i1 %B 111 } 112 113 define i1 @ashr_icmp2(i64 %X) nounwind { 114 ; CHECK-LABEL: @ashr_icmp2( 115 ; CHECK-NEXT: [[Z:%.*]] = icmp slt i64 %X, 16 116 ; CHECK-NEXT: ret i1 [[Z]] 117 ; 118 %Y = ashr exact i64 %X, 2 ; x / 4 119 %Z = icmp slt i64 %Y, 4 ; x < 16 120 ret i1 %Z 121 } 122 123 ; PR9998 124 ; Make sure we don't transform the ashr here into an sdiv 125 define i1 @pr9998(i32 %V) nounwind { 126 ; CHECK-LABEL: @pr9998( 127 ; CHECK-NEXT: [[W_MASK:%.*]] = and i32 %V, 1 128 ; CHECK-NEXT: [[Z:%.*]] = icmp ne i32 [[W_MASK]], 0 129 ; CHECK-NEXT: ret i1 [[Z]] 130 ; 131 %W = shl i32 %V, 31 132 %X = ashr exact i32 %W, 31 133 %Y = sext i32 %X to i64 134 %Z = icmp ugt i64 %Y, 7297771788697658747 135 ret i1 %Z 136 } 137 138 define i1 @udiv_icmp1(i64 %X) { 139 ; CHECK-LABEL: @udiv_icmp1( 140 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 %X, 0 141 ; CHECK-NEXT: ret i1 [[TMP1]] 142 ; 143 %A = udiv exact i64 %X, 5 ; X/5 144 %B = icmp ne i64 %A, 0 145 ret i1 %B 146 } 147 148 define i1 @udiv_icmp2(i64 %X) { 149 ; CHECK-LABEL: @udiv_icmp2( 150 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 0 151 ; CHECK-NEXT: ret i1 [[TMP1]] 152 ; 153 %A = udiv exact i64 %X, 5 ; X/5 == 0 --> x == 0 154 %B = icmp eq i64 %A, 0 155 ret i1 %B 156 } 157 158 define i1 @sdiv_icmp1(i64 %X) { 159 ; CHECK-LABEL: @sdiv_icmp1( 160 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 0 161 ; CHECK-NEXT: ret i1 [[TMP1]] 162 ; 163 %A = sdiv exact i64 %X, 5 ; X/5 == 0 --> x == 0 164 %B = icmp eq i64 %A, 0 165 ret i1 %B 166 } 167 168 define i1 @sdiv_icmp2(i64 %X) { 169 ; CHECK-LABEL: @sdiv_icmp2( 170 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 5 171 ; CHECK-NEXT: ret i1 [[TMP1]] 172 ; 173 %A = sdiv exact i64 %X, 5 ; X/5 == 1 --> x == 5 174 %B = icmp eq i64 %A, 1 175 ret i1 %B 176 } 177 178 define i1 @sdiv_icmp3(i64 %X) { 179 ; CHECK-LABEL: @sdiv_icmp3( 180 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, -5 181 ; CHECK-NEXT: ret i1 [[TMP1]] 182 ; 183 %A = sdiv exact i64 %X, 5 ; X/5 == -1 --> x == -5 184 %B = icmp eq i64 %A, -1 185 ret i1 %B 186 } 187 188 define i1 @sdiv_icmp4(i64 %X) { 189 ; CHECK-LABEL: @sdiv_icmp4( 190 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 0 191 ; CHECK-NEXT: ret i1 [[TMP1]] 192 ; 193 %A = sdiv exact i64 %X, -5 ; X/-5 == 0 --> x == 0 194 %B = icmp eq i64 %A, 0 195 ret i1 %B 196 } 197 198 define i1 @sdiv_icmp5(i64 %X) { 199 ; CHECK-LABEL: @sdiv_icmp5( 200 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, -5 201 ; CHECK-NEXT: ret i1 [[TMP1]] 202 ; 203 %A = sdiv exact i64 %X, -5 ; X/-5 == 1 --> x == -5 204 %B = icmp eq i64 %A, 1 205 ret i1 %B 206 } 207 208 define i1 @sdiv_icmp6(i64 %X) { 209 ; CHECK-LABEL: @sdiv_icmp6( 210 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 5 211 ; CHECK-NEXT: ret i1 [[TMP1]] 212 ; 213 %A = sdiv exact i64 %X, -5 ; X/-5 == 1 --> x == 5 214 %B = icmp eq i64 %A, -1 215 ret i1 %B 216 } 217 218