1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4define 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 13define 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 22define <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 31define 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 42define 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 51define 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 62define 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 72define 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 81define 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 91define 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 103define 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 113define 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 125define 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 138define 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 148define 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 158define 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 168define 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 178define 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 188define 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 198define 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 208define 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