1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -instcombine < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; return mul(zext x, zext y) > MAX 4*9880d681SAndroid Build Coastguard Workerdefine i32 @pr4917_1(i32 %x, i32 %y) nounwind { 5*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr4917_1( 6*9880d681SAndroid Build Coastguard Workerentry: 7*9880d681SAndroid Build Coastguard Worker %l = zext i32 %x to i64 8*9880d681SAndroid Build Coastguard Worker %r = zext i32 %y to i64 9*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: zext i32 10*9880d681SAndroid Build Coastguard Worker %mul64 = mul i64 %l, %r 11*9880d681SAndroid Build Coastguard Worker; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y) 12*9880d681SAndroid Build Coastguard Worker %overflow = icmp ugt i64 %mul64, 4294967295 13*9880d681SAndroid Build Coastguard Worker; CHECK: extractvalue { i32, i1 } [[MUL]], 1 14*9880d681SAndroid Build Coastguard Worker %retval = zext i1 %overflow to i32 15*9880d681SAndroid Build Coastguard Worker ret i32 %retval 16*9880d681SAndroid Build Coastguard Worker} 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker; return mul(zext x, zext y) >= MAX+1 19*9880d681SAndroid Build Coastguard Workerdefine i32 @pr4917_1a(i32 %x, i32 %y) nounwind { 20*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr4917_1a( 21*9880d681SAndroid Build Coastguard Workerentry: 22*9880d681SAndroid Build Coastguard Worker %l = zext i32 %x to i64 23*9880d681SAndroid Build Coastguard Worker %r = zext i32 %y to i64 24*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: zext i32 25*9880d681SAndroid Build Coastguard Worker %mul64 = mul i64 %l, %r 26*9880d681SAndroid Build Coastguard Worker; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y) 27*9880d681SAndroid Build Coastguard Worker %overflow = icmp uge i64 %mul64, 4294967296 28*9880d681SAndroid Build Coastguard Worker; CHECK: extractvalue { i32, i1 } [[MUL]], 1 29*9880d681SAndroid Build Coastguard Worker %retval = zext i1 %overflow to i32 30*9880d681SAndroid Build Coastguard Worker ret i32 %retval 31*9880d681SAndroid Build Coastguard Worker} 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker; mul(zext x, zext y) > MAX 34*9880d681SAndroid Build Coastguard Worker; mul(x, y) is used 35*9880d681SAndroid Build Coastguard Workerdefine i32 @pr4917_2(i32 %x, i32 %y) nounwind { 36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr4917_2( 37*9880d681SAndroid Build Coastguard Workerentry: 38*9880d681SAndroid Build Coastguard Worker %l = zext i32 %x to i64 39*9880d681SAndroid Build Coastguard Worker %r = zext i32 %y to i64 40*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: zext i32 41*9880d681SAndroid Build Coastguard Worker %mul64 = mul i64 %l, %r 42*9880d681SAndroid Build Coastguard Worker; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y) 43*9880d681SAndroid Build Coastguard Worker %overflow = icmp ugt i64 %mul64, 4294967295 44*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[VAL:%.*]] = extractvalue { i32, i1 } [[MUL]], 0 45*9880d681SAndroid Build Coastguard Worker %mul32 = trunc i64 %mul64 to i32 46*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[OVFL:%.*]] = extractvalue { i32, i1 } [[MUL]], 1 47*9880d681SAndroid Build Coastguard Worker %retval = select i1 %overflow, i32 %mul32, i32 111 48*9880d681SAndroid Build Coastguard Worker; CHECK: select i1 [[OVFL]], i32 [[VAL]] 49*9880d681SAndroid Build Coastguard Worker ret i32 %retval 50*9880d681SAndroid Build Coastguard Worker} 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker; return mul(zext x, zext y) > MAX 53*9880d681SAndroid Build Coastguard Worker; mul is used in non-truncate 54*9880d681SAndroid Build Coastguard Workerdefine i64 @pr4917_3(i32 %x, i32 %y) nounwind { 55*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr4917_3( 56*9880d681SAndroid Build Coastguard Workerentry: 57*9880d681SAndroid Build Coastguard Worker %l = zext i32 %x to i64 58*9880d681SAndroid Build Coastguard Worker %r = zext i32 %y to i64 59*9880d681SAndroid Build Coastguard Worker %mul64 = mul i64 %l, %r 60*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: umul.with.overflow.i32 61*9880d681SAndroid Build Coastguard Worker %overflow = icmp ugt i64 %mul64, 4294967295 62*9880d681SAndroid Build Coastguard Worker %retval = select i1 %overflow, i64 %mul64, i64 111 63*9880d681SAndroid Build Coastguard Worker ret i64 %retval 64*9880d681SAndroid Build Coastguard Worker} 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker; return mul(zext x, zext y) <= MAX 67*9880d681SAndroid Build Coastguard Workerdefine i32 @pr4917_4(i32 %x, i32 %y) nounwind { 68*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr4917_4( 69*9880d681SAndroid Build Coastguard Workerentry: 70*9880d681SAndroid Build Coastguard Worker %l = zext i32 %x to i64 71*9880d681SAndroid Build Coastguard Worker %r = zext i32 %y to i64 72*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: zext i32 73*9880d681SAndroid Build Coastguard Worker %mul64 = mul i64 %l, %r 74*9880d681SAndroid Build Coastguard Worker; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y) 75*9880d681SAndroid Build Coastguard Worker %overflow = icmp ule i64 %mul64, 4294967295 76*9880d681SAndroid Build Coastguard Worker; CHECK: extractvalue { i32, i1 } [[MUL]], 1 77*9880d681SAndroid Build Coastguard Worker; CHECK: xor 78*9880d681SAndroid Build Coastguard Worker %retval = zext i1 %overflow to i32 79*9880d681SAndroid Build Coastguard Worker ret i32 %retval 80*9880d681SAndroid Build Coastguard Worker} 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker; return mul(zext x, zext y) < MAX+1 83*9880d681SAndroid Build Coastguard Workerdefine i32 @pr4917_4a(i32 %x, i32 %y) nounwind { 84*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr4917_4a( 85*9880d681SAndroid Build Coastguard Workerentry: 86*9880d681SAndroid Build Coastguard Worker %l = zext i32 %x to i64 87*9880d681SAndroid Build Coastguard Worker %r = zext i32 %y to i64 88*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: zext i32 89*9880d681SAndroid Build Coastguard Worker %mul64 = mul i64 %l, %r 90*9880d681SAndroid Build Coastguard Worker; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y) 91*9880d681SAndroid Build Coastguard Worker %overflow = icmp ult i64 %mul64, 4294967296 92*9880d681SAndroid Build Coastguard Worker; CHECK: extractvalue { i32, i1 } [[MUL]], 1 93*9880d681SAndroid Build Coastguard Worker; CHECK: xor 94*9880d681SAndroid Build Coastguard Worker %retval = zext i1 %overflow to i32 95*9880d681SAndroid Build Coastguard Worker ret i32 %retval 96*9880d681SAndroid Build Coastguard Worker} 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker; operands of mul are of different size 99*9880d681SAndroid Build Coastguard Workerdefine i32 @pr4917_5(i32 %x, i8 %y) nounwind { 100*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr4917_5( 101*9880d681SAndroid Build Coastguard Workerentry: 102*9880d681SAndroid Build Coastguard Worker %l = zext i32 %x to i64 103*9880d681SAndroid Build Coastguard Worker %r = zext i8 %y to i64 104*9880d681SAndroid Build Coastguard Worker; CHECK: [[Y:%.*]] = zext i8 %y to i32 105*9880d681SAndroid Build Coastguard Worker %mul64 = mul i64 %l, %r 106*9880d681SAndroid Build Coastguard Worker %overflow = icmp ugt i64 %mul64, 4294967295 107*9880d681SAndroid Build Coastguard Worker %mul32 = trunc i64 %mul64 to i32 108*9880d681SAndroid Build Coastguard Worker; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 [[Y]]) 109*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[VAL:%.*]] = extractvalue { i32, i1 } [[MUL]], 0 110*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: [[OVFL:%.*]] = extractvalue { i32, i1 } [[MUL]], 1 111*9880d681SAndroid Build Coastguard Worker %retval = select i1 %overflow, i32 %mul32, i32 111 112*9880d681SAndroid Build Coastguard Worker; CHECK: select i1 [[OVFL]], i32 [[VAL]] 113*9880d681SAndroid Build Coastguard Worker ret i32 %retval 114*9880d681SAndroid Build Coastguard Worker} 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker; mul(zext x, zext y) != zext trunc mul 117*9880d681SAndroid Build Coastguard Workerdefine i32 @pr4918_1(i32 %x, i32 %y) nounwind { 118*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr4918_1( 119*9880d681SAndroid Build Coastguard Workerentry: 120*9880d681SAndroid Build Coastguard Worker %l = zext i32 %x to i64 121*9880d681SAndroid Build Coastguard Worker %r = zext i32 %y to i64 122*9880d681SAndroid Build Coastguard Worker %mul64 = mul i64 %l, %r 123*9880d681SAndroid Build Coastguard Worker; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y) 124*9880d681SAndroid Build Coastguard Worker %part32 = trunc i64 %mul64 to i32 125*9880d681SAndroid Build Coastguard Worker %part64 = zext i32 %part32 to i64 126*9880d681SAndroid Build Coastguard Worker %overflow = icmp ne i64 %mul64, %part64 127*9880d681SAndroid Build Coastguard Worker; CHECK: [[OVFL:%.*]] = extractvalue { i32, i1 } [[MUL:%.*]], 1 128*9880d681SAndroid Build Coastguard Worker %retval = zext i1 %overflow to i32 129*9880d681SAndroid Build Coastguard Worker ret i32 %retval 130*9880d681SAndroid Build Coastguard Worker} 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker; mul(zext x, zext y) == zext trunc mul 133*9880d681SAndroid Build Coastguard Workerdefine i32 @pr4918_2(i32 %x, i32 %y) nounwind { 134*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr4918_2( 135*9880d681SAndroid Build Coastguard Workerentry: 136*9880d681SAndroid Build Coastguard Worker %l = zext i32 %x to i64 137*9880d681SAndroid Build Coastguard Worker %r = zext i32 %y to i64 138*9880d681SAndroid Build Coastguard Worker %mul64 = mul i64 %l, %r 139*9880d681SAndroid Build Coastguard Worker; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y) 140*9880d681SAndroid Build Coastguard Worker %part32 = trunc i64 %mul64 to i32 141*9880d681SAndroid Build Coastguard Worker %part64 = zext i32 %part32 to i64 142*9880d681SAndroid Build Coastguard Worker %overflow = icmp eq i64 %mul64, %part64 143*9880d681SAndroid Build Coastguard Worker; CHECK: extractvalue { i32, i1 } [[MUL]] 144*9880d681SAndroid Build Coastguard Worker %retval = zext i1 %overflow to i32 145*9880d681SAndroid Build Coastguard Worker; CHECK: xor 146*9880d681SAndroid Build Coastguard Worker ret i32 %retval 147*9880d681SAndroid Build Coastguard Worker} 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker; zext trunc mul != mul(zext x, zext y) 150*9880d681SAndroid Build Coastguard Workerdefine i32 @pr4918_3(i32 %x, i32 %y) nounwind { 151*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr4918_3( 152*9880d681SAndroid Build Coastguard Workerentry: 153*9880d681SAndroid Build Coastguard Worker %l = zext i32 %x to i64 154*9880d681SAndroid Build Coastguard Worker %r = zext i32 %y to i64 155*9880d681SAndroid Build Coastguard Worker %mul64 = mul i64 %l, %r 156*9880d681SAndroid Build Coastguard Worker; CHECK: [[MUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y) 157*9880d681SAndroid Build Coastguard Worker %part32 = trunc i64 %mul64 to i32 158*9880d681SAndroid Build Coastguard Worker %part64 = zext i32 %part32 to i64 159*9880d681SAndroid Build Coastguard Worker %overflow = icmp ne i64 %part64, %mul64 160*9880d681SAndroid Build Coastguard Worker; CHECK: extractvalue { i32, i1 } [[MUL]], 1 161*9880d681SAndroid Build Coastguard Worker %retval = zext i1 %overflow to i32 162*9880d681SAndroid Build Coastguard Worker ret i32 %retval 163*9880d681SAndroid Build Coastguard Worker} 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Workerdefine <4 x i32> @pr20113(<4 x i16> %a, <4 x i16> %b) { 166*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr20113 167*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mul.with.overflow 168*9880d681SAndroid Build Coastguard Worker; CHECK: ret 169*9880d681SAndroid Build Coastguard Worker %vmovl.i.i726 = zext <4 x i16> %a to <4 x i32> 170*9880d681SAndroid Build Coastguard Worker %vmovl.i.i712 = zext <4 x i16> %b to <4 x i32> 171*9880d681SAndroid Build Coastguard Worker %mul.i703 = mul <4 x i32> %vmovl.i.i712, %vmovl.i.i726 172*9880d681SAndroid Build Coastguard Worker %tmp = icmp sge <4 x i32> %mul.i703, zeroinitializer 173*9880d681SAndroid Build Coastguard Worker %vcgez.i = sext <4 x i1> %tmp to <4 x i32> 174*9880d681SAndroid Build Coastguard Worker ret <4 x i32> %vcgez.i 175*9880d681SAndroid Build Coastguard Worker} 176*9880d681SAndroid Build Coastguard Worker 177*9880d681SAndroid Build Coastguard Worker 178*9880d681SAndroid Build Coastguard Worker; The last test needs this weird datalayout. 179*9880d681SAndroid Build Coastguard Workertarget datalayout = "i32:8:8" 180*9880d681SAndroid Build Coastguard Worker; Without it, InstCombine will align the pointed on 4 Bytes 181*9880d681SAndroid Build Coastguard Worker; The KnownBitsZero that result from the alignment allows to 182*9880d681SAndroid Build Coastguard Worker; turn: 183*9880d681SAndroid Build Coastguard Worker; and i32 %mul, 255 184*9880d681SAndroid Build Coastguard Worker; to: 185*9880d681SAndroid Build Coastguard Worker; and i32 %mul, 252 186*9880d681SAndroid Build Coastguard Worker; The mask is no longer in the form 2^n-1 and this prevents the transformation. 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Worker@pr21445_data = external global i32 189*9880d681SAndroid Build Coastguard Workerdefine i1 @pr21445(i8 %a) { 190*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr21445( 191*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %[[umul:.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %a, i8 ptrtoint (i32* @pr21445_data to i8)) 192*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %[[cmp:.*]] = extractvalue { i8, i1 } %[[umul]], 1 193*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i1 %[[cmp]] 194*9880d681SAndroid Build Coastguard Worker %ext = zext i8 %a to i32 195*9880d681SAndroid Build Coastguard Worker %mul = mul i32 %ext, zext (i8 ptrtoint (i32* @pr21445_data to i8) to i32) 196*9880d681SAndroid Build Coastguard Worker %and = and i32 %mul, 255 197*9880d681SAndroid Build Coastguard Worker %cmp = icmp ne i32 %mul, %and 198*9880d681SAndroid Build Coastguard Worker ret i1 %cmp 199*9880d681SAndroid Build Coastguard Worker} 200