218 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; PR1293635 6; ext split from i32 to i1287define i128 @i128_ext_split(i32 noundef %x) {8; CHECK-LABEL: define i128 @i128_ext_split(9; CHECK-SAME: i32 noundef [[X:%.*]]) {10; CHECK-NEXT: [[XX:%.*]] = sext i32 [[X]] to i12811; CHECK-NEXT: ret i128 [[XX]]12;13 %LowerSrc = sext i32 %x to i6414 %sign = ashr i32 %x, 3115 %UpperSrc = sext i32 %sign to i6416 %widen = zext i64 %UpperSrc to i12817 %hi = shl nuw i128 %widen, 6418 %lo = zext i64 %LowerSrc to i12819 %res = or disjoint i128 %hi, %lo20 ret i128 %res21}22 23; ext split from i32 to i12824define void @i128_ext_split_store(i32 %x, ptr %out) {25; CHECK-LABEL: define void @i128_ext_split_store(26; CHECK-SAME: i32 [[X:%.*]], ptr [[OUT:%.*]]) {27; CHECK-NEXT: [[ENTRY:.*:]]28; CHECK-NEXT: [[RES:%.*]] = sext i32 [[X]] to i12829; CHECK-NEXT: store i128 [[RES]], ptr [[OUT]], align 1630; CHECK-NEXT: ret void31;32entry:33 %LowerSrc = sext i32 %x to i6434 %lo = zext i64 %LowerSrc to i12835 36 %sign = ashr i32 %x, 3137 %UpperSrc = sext i32 %sign to i6438 %widen = zext i64 %UpperSrc to i12839 %hi = shl nuw i128 %widen, 6440 41 %res = or disjoint i128 %hi, %lo42 store i128 %res, ptr %out, align 1643 ret void44}45 46; ext split from i16 to i6447define void @i64_ext_split_store(i16 %x, ptr %out) {48; CHECK-LABEL: define void @i64_ext_split_store(49; CHECK-SAME: i16 [[X:%.*]], ptr [[OUT:%.*]]) {50; CHECK-NEXT: [[ENTRY:.*:]]51; CHECK-NEXT: [[RES:%.*]] = sext i16 [[X]] to i6452; CHECK-NEXT: store i64 [[RES]], ptr [[OUT]], align 1653; CHECK-NEXT: ret void54;55entry:56 %LowerSrc = sext i16 %x to i3257 %lo = zext i32 %LowerSrc to i6458 59 %sign = ashr i16 %x, 1560 %UpperSrc = sext i16 %sign to i3261 %widen = zext i32 %UpperSrc to i6462 %hi = shl nuw i64 %widen, 3263 64 %res = or disjoint i64 %hi, %lo65 store i64 %res, ptr %out, align 1666 ret void67}68 69; ext split from i16 to i12870define void @i128_ext_split_store_i16(i16 %x, ptr %out) {71; CHECK-LABEL: define void @i128_ext_split_store_i16(72; CHECK-SAME: i16 [[X:%.*]], ptr [[OUT:%.*]]) {73; CHECK-NEXT: [[ENTRY:.*:]]74; CHECK-NEXT: [[RES:%.*]] = sext i16 [[X]] to i12875; CHECK-NEXT: store i128 [[RES]], ptr [[OUT]], align 1676; CHECK-NEXT: ret void77;78entry:79 %LowerSrc = sext i16 %x to i6480 %lo = zext i64 %LowerSrc to i12881 82 %sign = ashr i16 %x, 1583 %UpperSrc = sext i16 %sign to i6484 %widen = zext i64 %UpperSrc to i12885 %hi = shl nuw i128 %widen, 6486 87 %res = or disjoint i128 %hi, %lo88 store i128 %res, ptr %out, align 1689 ret void90}91 92; (non)ext split from i64 to i12893define void @i128_ext_split_store_i64(i64 %x, ptr %out) {94; CHECK-LABEL: define void @i128_ext_split_store_i64(95; CHECK-SAME: i64 [[X:%.*]], ptr [[OUT:%.*]]) {96; CHECK-NEXT: [[ENTRY:.*:]]97; CHECK-NEXT: [[RES:%.*]] = sext i64 [[X]] to i12898; CHECK-NEXT: store i128 [[RES]], ptr [[OUT]], align 1699; CHECK-NEXT: ret void100;101entry:102 %lo = zext i64 %x to i128103 104 %sign = ashr i64 %x, 63105 %widen = zext i64 %sign to i128106 %hi = shl nuw i128 %widen, 64107 108 %res = or disjoint i128 %hi, %lo109 store i128 %res, ptr %out, align 16110 ret void111}112 113; negative test - wrong constant value114define i128 @i128_ext_split_neg1(i32 %x) {115; CHECK-LABEL: define i128 @i128_ext_split_neg1(116; CHECK-SAME: i32 [[X:%.*]]) {117; CHECK-NEXT: [[ENTRY:.*:]]118; CHECK-NEXT: [[LOWERSRC:%.*]] = sext i32 [[X]] to i64119; CHECK-NEXT: [[LO:%.*]] = zext i64 [[LOWERSRC]] to i128120; CHECK-NEXT: [[SIGN:%.*]] = ashr i32 [[X]], 31121; CHECK-NEXT: [[UPPERSRC:%.*]] = sext i32 [[SIGN]] to i64122; CHECK-NEXT: [[WIDEN:%.*]] = zext i64 [[UPPERSRC]] to i128123; CHECK-NEXT: [[HI:%.*]] = shl nuw i128 [[WIDEN]], 65124; CHECK-NEXT: [[RES:%.*]] = or disjoint i128 [[HI]], [[LO]]125; CHECK-NEXT: ret i128 [[RES]]126;127entry:128 %LowerSrc = sext i32 %x to i64129 %lo = zext i64 %LowerSrc to i128130 131 %sign = ashr i32 %x, 31132 %UpperSrc = sext i32 %sign to i64133 %widen = zext i64 %UpperSrc to i128134 %hi = shl nuw i128 %widen, 65135 136 %res = or disjoint i128 %hi, %lo137 ret i128 %res138}139 140; negative test - wrong shift value141define i128 @i128_ext_split_neg2(i32 %x) {142; CHECK-LABEL: define i128 @i128_ext_split_neg2(143; CHECK-SAME: i32 [[X:%.*]]) {144; CHECK-NEXT: [[ENTRY:.*:]]145; CHECK-NEXT: [[LOWERSRC:%.*]] = sext i32 [[X]] to i64146; CHECK-NEXT: [[LO:%.*]] = zext i64 [[LOWERSRC]] to i128147; CHECK-NEXT: [[SIGN:%.*]] = ashr i32 [[X]], 3148; CHECK-NEXT: [[UPPERSRC:%.*]] = sext i32 [[SIGN]] to i64149; CHECK-NEXT: [[WIDEN:%.*]] = zext i64 [[UPPERSRC]] to i128150; CHECK-NEXT: [[HI:%.*]] = shl nuw i128 [[WIDEN]], 64151; CHECK-NEXT: [[RES:%.*]] = or disjoint i128 [[HI]], [[LO]]152; CHECK-NEXT: ret i128 [[RES]]153;154entry:155 %LowerSrc = sext i32 %x to i64156 %lo = zext i64 %LowerSrc to i128157 158 %sign = ashr i32 %x, 3159 %UpperSrc = sext i32 %sign to i64160 %widen = zext i64 %UpperSrc to i128161 %hi = shl nuw i128 %widen, 64162 163 %res = or disjoint i128 %hi, %lo164 ret i128 %res165}166 167; negative test - wrong ext instruction168define i128 @i128_ext_split_neg3(i32 %x) {169; CHECK-LABEL: define i128 @i128_ext_split_neg3(170; CHECK-SAME: i32 [[X:%.*]]) {171; CHECK-NEXT: [[ENTRY:.*:]]172; CHECK-NEXT: [[LO:%.*]] = zext i32 [[X]] to i128173; CHECK-NEXT: [[SIGN:%.*]] = ashr i32 [[X]], 31174; CHECK-NEXT: [[UPPERSRC:%.*]] = sext i32 [[SIGN]] to i64175; CHECK-NEXT: [[WIDEN:%.*]] = zext i64 [[UPPERSRC]] to i128176; CHECK-NEXT: [[HI:%.*]] = shl nuw i128 [[WIDEN]], 64177; CHECK-NEXT: [[RES:%.*]] = or disjoint i128 [[HI]], [[LO]]178; CHECK-NEXT: ret i128 [[RES]]179;180entry:181 %LowerSrc = zext i32 %x to i64182 %lo = zext i64 %LowerSrc to i128183 184 %sign = ashr i32 %x, 31185 %UpperSrc = sext i32 %sign to i64186 %widen = zext i64 %UpperSrc to i128187 %hi = shl nuw i128 %widen, 64188 189 %res = or disjoint i128 %hi, %lo190 ret i128 %res191}192 193; negative test - wrong shift194define i128 @i128_ext_split_neg4(i32 %x) {195; CHECK-LABEL: define i128 @i128_ext_split_neg4(196; CHECK-SAME: i32 [[X:%.*]]) {197; CHECK-NEXT: [[ENTRY:.*:]]198; CHECK-NEXT: [[LOWERSRC:%.*]] = sext i32 [[X]] to i64199; CHECK-NEXT: [[LO:%.*]] = zext i64 [[LOWERSRC]] to i128200; CHECK-NEXT: [[SIGN:%.*]] = lshr i32 [[X]], 31201; CHECK-NEXT: [[WIDEN:%.*]] = zext nneg i32 [[SIGN]] to i128202; CHECK-NEXT: [[HI:%.*]] = shl nuw nsw i128 [[WIDEN]], 64203; CHECK-NEXT: [[RES:%.*]] = or disjoint i128 [[HI]], [[LO]]204; CHECK-NEXT: ret i128 [[RES]]205;206entry:207 %LowerSrc = sext i32 %x to i64208 %lo = zext i64 %LowerSrc to i128209 210 %sign = lshr i32 %x, 31211 %UpperSrc = sext i32 %sign to i64212 %widen = zext i64 %UpperSrc to i128213 %hi = shl nuw i128 %widen, 64214 215 %res = or disjoint i128 %hi, %lo216 ret i128 %res217}218