243 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -passes=instcombine %s -S | FileCheck %s3 4declare void @use.i32(i32)5declare void @use.i64(i64)6 7define i64 @full_shl(i32 %x) {8; CHECK-LABEL: define i64 @full_shl(9; CHECK-SAME: i32 [[X:%.*]]) {10; CHECK-NEXT: [[X_ZEXT:%.*]] = zext i32 [[X]] to i6411; CHECK-NEXT: [[LO_SHL:%.*]] = shl nuw nsw i64 [[X_ZEXT]], 2412; CHECK-NEXT: ret i64 [[LO_SHL]]13;14 %lo = and i32 %x, u0xffff15 %lo.zext = zext nneg i32 %lo to i6416 %lo.shl = shl nuw nsw i64 %lo.zext, 2417 18 %hi = lshr i32 %x, 1619 %hi.zext = zext nneg i32 %hi to i6420 %hi.shl = shl nuw nsw i64 %hi.zext, 4021 22 %res = or disjoint i64 %lo.shl, %hi.shl23 ret i64 %res24}25 26define <2 x i64> @full_shl_vec(<2 x i32> %v) {27; CHECK-LABEL: define <2 x i64> @full_shl_vec(28; CHECK-SAME: <2 x i32> [[V:%.*]]) {29; CHECK-NEXT: [[V_ZEXT:%.*]] = zext <2 x i32> [[V]] to <2 x i64>30; CHECK-NEXT: [[LO_SHL:%.*]] = shl nuw nsw <2 x i64> [[V_ZEXT]], splat (i64 24)31; CHECK-NEXT: ret <2 x i64> [[LO_SHL]]32;33 %lo = and <2 x i32> %v, splat(i32 u0xffff)34 %lo.zext = zext nneg <2 x i32> %lo to <2 x i64>35 %lo.shl = shl nuw nsw <2 x i64> %lo.zext, splat(i64 24)36 37 %hi = lshr <2 x i32> %v, splat(i32 16)38 %hi.zext = zext nneg <2 x i32> %hi to <2 x i64>39 %hi.shl = shl nuw nsw <2 x i64> %hi.zext, splat(i64 40)40 41 %res = or disjoint <2 x i64> %lo.shl, %hi.shl42 ret <2 x i64> %res43}44 45; u0xaabbccdd = -143053289946define i64 @partial_shl(i32 %x) {47; CHECK-LABEL: define i64 @partial_shl(48; CHECK-SAME: i32 [[X:%.*]]) {49; CHECK-NEXT: [[X_MASK:%.*]] = and i32 [[X]], -143053289950; CHECK-NEXT: [[X_ZEXT:%.*]] = zext i32 [[X_MASK]] to i6451; CHECK-NEXT: [[LO_SHL:%.*]] = shl nuw nsw i64 [[X_ZEXT]], 2452; CHECK-NEXT: ret i64 [[LO_SHL]]53;54 %lo = and i32 %x, u0xccdd55 %lo.zext = zext nneg i32 %lo to i6456 %lo.shl = shl nuw nsw i64 %lo.zext, 2457 58 %hi = lshr i32 %x, 1659 %hi.mask = and i32 %hi, u0xaabb60 %hi.zext = zext nneg i32 %hi.mask to i6461 %hi.shl = shl nuw nsw i64 %hi.zext, 4062 63 %res = or disjoint i64 %lo.shl, %hi.shl64 ret i64 %res65}66 67define i64 @shl_multi_use_shl(i32 %x) {68; CHECK-LABEL: define i64 @shl_multi_use_shl(69; CHECK-SAME: i32 [[X:%.*]]) {70; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X]], 2471; CHECK-NEXT: [[LO_SHL:%.*]] = zext i32 [[TMP1]] to i6472; CHECK-NEXT: call void @use.i64(i64 [[LO_SHL]])73; CHECK-NEXT: [[HI:%.*]] = lshr i32 [[X]], 1674; CHECK-NEXT: [[HI_ZEXT:%.*]] = zext nneg i32 [[HI]] to i6475; CHECK-NEXT: [[HI_SHL:%.*]] = shl nuw nsw i64 [[HI_ZEXT]], 4076; CHECK-NEXT: [[RES:%.*]] = or disjoint i64 [[HI_SHL]], [[LO_SHL]]77; CHECK-NEXT: ret i64 [[RES]]78;79 %lo = and i32 %x, u0x00ff80 %lo.zext = zext nneg i32 %lo to i6481 %lo.shl = shl nuw nsw i64 %lo.zext, 2482 call void @use.i64(i64 %lo.shl)83 84 %hi = lshr i32 %x, 1685 %hi.zext = zext nneg i32 %hi to i6486 %hi.shl = shl nuw nsw i64 %hi.zext, 4087 88 %res = or disjoint i64 %lo.shl, %hi.shl89 ret i64 %res90}91 92define i64 @shl_multi_use_zext(i32 %x) {93; CHECK-LABEL: define i64 @shl_multi_use_zext(94; CHECK-SAME: i32 [[X:%.*]]) {95; CHECK-NEXT: [[LO:%.*]] = and i32 [[X]], 25596; CHECK-NEXT: [[LO_ZEXT:%.*]] = zext nneg i32 [[LO]] to i6497; CHECK-NEXT: call void @use.i64(i64 [[LO_ZEXT]])98; CHECK-NEXT: [[LO_SHL:%.*]] = shl nuw nsw i64 [[LO_ZEXT]], 2499; CHECK-NEXT: [[HI:%.*]] = lshr i32 [[X]], 16100; CHECK-NEXT: [[HI_ZEXT:%.*]] = zext nneg i32 [[HI]] to i64101; CHECK-NEXT: [[HI_SHL:%.*]] = shl nuw nsw i64 [[HI_ZEXT]], 40102; CHECK-NEXT: [[RES:%.*]] = or disjoint i64 [[LO_SHL]], [[HI_SHL]]103; CHECK-NEXT: ret i64 [[RES]]104;105 %lo = and i32 %x, u0x00ff106 %lo.zext = zext nneg i32 %lo to i64107 call void @use.i64(i64 %lo.zext)108 %lo.shl = shl nuw nsw i64 %lo.zext, 24109 110 %hi = lshr i32 %x, 16111 %hi.zext = zext nneg i32 %hi to i64112 %hi.shl = shl nuw nsw i64 %hi.zext, 40113 114 %res = or disjoint i64 %lo.shl, %hi.shl115 ret i64 %res116}117 118define i64 @shl_multi_use_lshr(i32 %x) {119; CHECK-LABEL: define i64 @shl_multi_use_lshr(120; CHECK-SAME: i32 [[X:%.*]]) {121; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X]], 24122; CHECK-NEXT: [[LO_SHL:%.*]] = zext i32 [[TMP1]] to i64123; CHECK-NEXT: [[HI:%.*]] = lshr i32 [[X]], 16124; CHECK-NEXT: call void @use.i32(i32 [[HI]])125; CHECK-NEXT: [[HI_ZEXT:%.*]] = zext nneg i32 [[HI]] to i64126; CHECK-NEXT: [[HI_SHL:%.*]] = shl nuw nsw i64 [[HI_ZEXT]], 40127; CHECK-NEXT: [[RES:%.*]] = or disjoint i64 [[HI_SHL]], [[LO_SHL]]128; CHECK-NEXT: ret i64 [[RES]]129;130 %lo = and i32 %x, u0x00ff131 %lo.zext = zext nneg i32 %lo to i64132 %lo.shl = shl nuw nsw i64 %lo.zext, 24133 134 %hi = lshr i32 %x, 16135 call void @use.i32(i32 %hi)136 %hi.zext = zext nneg i32 %hi to i64137 %hi.shl = shl nuw nsw i64 %hi.zext, 40138 139 %res = or disjoint i64 %lo.shl, %hi.shl140 ret i64 %res141}142 143define i64 @shl_non_disjoint(i32 %x) {144; CHECK-LABEL: define i64 @shl_non_disjoint(145; CHECK-SAME: i32 [[X:%.*]]) {146; CHECK-NEXT: [[LO:%.*]] = and i32 [[X]], 16711680147; CHECK-NEXT: [[LO_ZEXT:%.*]] = zext nneg i32 [[LO]] to i64148; CHECK-NEXT: [[LO_SHL:%.*]] = shl nuw nsw i64 [[LO_ZEXT]], 24149; CHECK-NEXT: [[HI:%.*]] = lshr i32 [[X]], 16150; CHECK-NEXT: call void @use.i32(i32 [[HI]])151; CHECK-NEXT: [[HI_ZEXT:%.*]] = zext nneg i32 [[HI]] to i64152; CHECK-NEXT: [[HI_SHL:%.*]] = shl nuw nsw i64 [[HI_ZEXT]], 40153; CHECK-NEXT: [[RES:%.*]] = or i64 [[LO_SHL]], [[HI_SHL]]154; CHECK-NEXT: ret i64 [[RES]]155;156 %lo = and i32 %x, u0x00ff0000157 %lo.zext = zext nneg i32 %lo to i64158 %lo.shl = shl nuw nsw i64 %lo.zext, 24159 160 %hi = lshr i32 %x, 16161 call void @use.i32(i32 %hi)162 %hi.zext = zext nneg i32 %hi to i64163 %hi.shl = shl nuw nsw i64 %hi.zext, 40164 165 %res = or i64 %lo.shl, %hi.shl166 ret i64 %res167}168 169define i64 @combine(i32 %lower, i32 %upper) {170; CHECK-LABEL: define i64 @combine(171; CHECK-SAME: i32 [[LOWER:%.*]], i32 [[UPPER:%.*]]) {172; CHECK-NEXT: [[BASE:%.*]] = zext i32 [[LOWER]] to i64173; CHECK-NEXT: [[UPPER_ZEXT:%.*]] = zext i32 [[UPPER]] to i64174; CHECK-NEXT: [[S_0:%.*]] = shl nuw i64 [[UPPER_ZEXT]], 32175; CHECK-NEXT: [[O_3:%.*]] = or disjoint i64 [[S_0]], [[BASE]]176; CHECK-NEXT: ret i64 [[O_3]]177;178 %base = zext i32 %lower to i64179 180 %u.0 = and i32 %upper, u0xff181 %z.0 = zext i32 %u.0 to i64182 %s.0 = shl i64 %z.0, 32183 %o.0 = or i64 %base, %s.0184 185 %r.1 = lshr i32 %upper, 8186 %u.1 = and i32 %r.1, u0xff187 %z.1 = zext i32 %u.1 to i64188 %s.1 = shl i64 %z.1, 40189 %o.1 = or i64 %o.0, %s.1190 191 %r.2 = lshr i32 %upper, 16192 %u.2 = and i32 %r.2, u0xff193 %z.2 = zext i32 %u.2 to i64194 %s.2 = shl i64 %z.2, 48195 %o.2 = or i64 %o.1, %s.2196 197 %r.3 = lshr i32 %upper, 24198 %u.3 = and i32 %r.3, u0xff199 %z.3 = zext i32 %u.3 to i64200 %s.3 = shl i64 %z.3, 56201 %o.3 = or i64 %o.2, %s.3202 203 ret i64 %o.3204}205 206define i64 @combine_2(i32 %lower, i32 %upper) {207; CHECK-LABEL: define i64 @combine_2(208; CHECK-SAME: i32 [[LOWER:%.*]], i32 [[UPPER:%.*]]) {209; CHECK-NEXT: [[BASE:%.*]] = zext i32 [[LOWER]] to i64210; CHECK-NEXT: [[S_03:%.*]] = zext i32 [[UPPER]] to i64211; CHECK-NEXT: [[O:%.*]] = shl nuw i64 [[S_03]], 32212; CHECK-NEXT: [[RES:%.*]] = or disjoint i64 [[O]], [[BASE]]213; CHECK-NEXT: ret i64 [[RES]]214;215 %base = zext i32 %lower to i64216 217 %u.0 = and i32 %upper, u0xff218 %z.0 = zext i32 %u.0 to i64219 %s.0 = shl i64 %z.0, 32220 221 %r.1 = lshr i32 %upper, 8222 %u.1 = and i32 %r.1, u0xff223 %z.1 = zext i32 %u.1 to i64224 %s.1 = shl i64 %z.1, 40225 %o.1 = or i64 %s.0, %s.1226 227 %r.2 = lshr i32 %upper, 16228 %u.2 = and i32 %r.2, u0xff229 %z.2 = zext i32 %u.2 to i64230 %s.2 = shl i64 %z.2, 48231 232 %r.3 = lshr i32 %upper, 24233 %u.3 = and i32 %r.3, u0xff234 %z.3 = zext i32 %u.3 to i64235 %s.3 = shl i64 %z.3, 56236 %o.3 = or i64 %s.2, %s.3237 238 %o = or i64 %o.1, %o.3239 %res = or i64 %o, %base240 241 ret i64 %res242}243