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