1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3 4declare void @escape(i16 %add) 5declare void @escape2(<2 x i16> %add) 6 7define void @numsignbits_shl_zext(i8 %x) { 8; CHECK-LABEL: define void @numsignbits_shl_zext( 9; CHECK-SAME: i8 [[X:%.*]]) { 10; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 5 11; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16 12; CHECK-NEXT: [[NSB4:%.*]] = shl i16 [[ZEXT]], 10 13; CHECK-NEXT: [[ADD14:%.*]] = and i16 [[NSB4]], 15360 14; CHECK-NEXT: call void @escape(i16 [[ADD14]]) 15; CHECK-NEXT: [[ADD13:%.*]] = and i16 [[NSB4]], 7168 16; CHECK-NEXT: call void @escape(i16 [[ADD13]]) 17; CHECK-NEXT: [[ADD12:%.*]] = and i16 [[NSB4]], 3072 18; CHECK-NEXT: call void @escape(i16 [[ADD12]]) 19; CHECK-NEXT: [[AND11:%.*]] = and i16 [[NSB4]], 2048 20; CHECK-NEXT: [[ADD11:%.*]] = add nsw i16 [[AND11]], [[NSB4]] 21; CHECK-NEXT: call void @escape(i16 [[ADD11]]) 22; CHECK-NEXT: ret void 23; 24 %ashr = ashr i8 %x, 5 25 %zext = zext i8 %ashr to i16 26 %nsb4 = shl i16 %zext, 10 27 ; Validate ComputeNumSignBits using this simplification: 28 ; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit 29 ; 4 sign bits: Goal is to fold away the add for bits 12-14. 30 %and14 = and i16 %nsb4, 16384 31 %add14 = add i16 %and14, %nsb4 32 call void @escape(i16 %add14) 33 %and13 = and i16 %nsb4, 8192 34 %add13 = add i16 %and13, %nsb4 35 call void @escape(i16 %add13) 36 %and12 = and i16 %nsb4, 4096 37 %add12 = add i16 %and12, %nsb4 38 call void @escape(i16 %add12) 39 %and11 = and i16 %nsb4, 2048 40 %add11 = add i16 %and11, %nsb4 41 call void @escape(i16 %add11) 42 ret void 43} 44 45define void @numsignbits_shl_zext_shift_amounr_matches_extend(i8 %x) { 46; CHECK-LABEL: define void @numsignbits_shl_zext_shift_amounr_matches_extend( 47; CHECK-SAME: i8 [[X:%.*]]) { 48; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 2 49; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16 50; CHECK-NEXT: [[NSB3:%.*]] = shl nuw i16 [[ZEXT]], 8 51; CHECK-NEXT: [[ADD14:%.*]] = and i16 [[NSB3]], 16128 52; CHECK-NEXT: call void @escape(i16 [[ADD14]]) 53; CHECK-NEXT: [[ADD13:%.*]] = and i16 [[NSB3]], 7936 54; CHECK-NEXT: call void @escape(i16 [[ADD13]]) 55; CHECK-NEXT: [[AND12:%.*]] = and i16 [[NSB3]], 4096 56; CHECK-NEXT: [[ADD12:%.*]] = add nsw i16 [[AND12]], [[NSB3]] 57; CHECK-NEXT: call void @escape(i16 [[ADD12]]) 58; CHECK-NEXT: ret void 59; 60 %ashr = ashr i8 %x, 2 61 %zext = zext i8 %ashr to i16 62 %nsb3 = shl i16 %zext, 8 63 ; Validate ComputeNumSignBits using this simplification: 64 ; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit 65 ; 3 sign bits: Goal is to fold away the add for bits 13-14. 66 %and14 = and i16 %nsb3, 16384 67 %add14 = add i16 %and14, %nsb3 68 call void @escape(i16 %add14) 69 %and13 = and i16 %nsb3, 8192 70 %add13 = add i16 %and13, %nsb3 71 call void @escape(i16 %add13) 72 %and12 = and i16 %nsb3, 4096 73 %add12 = add i16 %and12, %nsb3 74 call void @escape(i16 %add12) 75 ret void 76} 77 78define void @numsignbits_shl_zext_extended_bits_remains(i8 %x) { 79; CHECK-LABEL: define void @numsignbits_shl_zext_extended_bits_remains( 80; CHECK-SAME: i8 [[X:%.*]]) { 81; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 5 82; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16 83; CHECK-NEXT: [[NSB1:%.*]] = shl nuw nsw i16 [[ZEXT]], 7 84; CHECK-NEXT: [[AND14:%.*]] = and i16 [[NSB1]], 16384 85; CHECK-NEXT: [[ADD14:%.*]] = add nuw i16 [[AND14]], [[NSB1]] 86; CHECK-NEXT: call void @escape(i16 [[ADD14]]) 87; CHECK-NEXT: ret void 88; 89 %ashr = ashr i8 %x, 5 90 %zext = zext i8 %ashr to i16 91 %nsb1 = shl i16 %zext, 7 92 ; Validate ComputeNumSignBits using this simplification: 93 ; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit 94 ; 1 sign bit: The add can't be folded away here. 95 %and14 = and i16 %nsb1, 16384 96 %add14 = add i16 %and14, %nsb1 97 call void @escape(i16 %add14) 98 ret void 99} 100 101define void @numsignbits_shl_zext_all_bits_shifted_out(i8 %x) { 102; CHECK-LABEL: define void @numsignbits_shl_zext_all_bits_shifted_out( 103; CHECK-SAME: i8 [[X:%.*]]) { 104; CHECK-NEXT: [[ASHR:%.*]] = lshr i8 [[X]], 5 105; CHECK-NEXT: [[ZEXT:%.*]] = zext nneg i8 [[ASHR]] to i16 106; CHECK-NEXT: [[NSB1:%.*]] = shl i16 [[ZEXT]], 14 107; CHECK-NEXT: [[AND14:%.*]] = and i16 [[NSB1]], 16384 108; CHECK-NEXT: [[ADD14:%.*]] = add i16 [[AND14]], [[NSB1]] 109; CHECK-NEXT: call void @escape(i16 [[ADD14]]) 110; CHECK-NEXT: ret void 111; 112 %ashr = ashr i8 %x, 5 113 %zext = zext i8 %ashr to i16 114 %nsb1 = shl i16 %zext, 14 115 ; Validate ComputeNumSignBits using this simplification: 116 ; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit 117 ; 1 sign bit: The add can't be folded away here. 118 %and14 = and i16 %nsb1, 16384 119 %add14 = add i16 %and14, %nsb1 120 call void @escape(i16 %add14) 121 ret void 122} 123 124define void @numsignbits_shl_zext_vector(<2 x i8> %x) { 125; CHECK-LABEL: define void @numsignbits_shl_zext_vector( 126; CHECK-SAME: <2 x i8> [[X:%.*]]) { 127; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i8> [[X]], splat (i8 5) 128; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[ASHR]] to <2 x i16> 129; CHECK-NEXT: [[NSB4:%.*]] = shl <2 x i16> [[ZEXT]], splat (i16 10) 130; CHECK-NEXT: [[ADD14:%.*]] = and <2 x i16> [[NSB4]], splat (i16 15360) 131; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD14]]) 132; CHECK-NEXT: [[ADD13:%.*]] = and <2 x i16> [[NSB4]], splat (i16 7168) 133; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD13]]) 134; CHECK-NEXT: [[ADD12:%.*]] = and <2 x i16> [[NSB4]], splat (i16 3072) 135; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD12]]) 136; CHECK-NEXT: [[AND11:%.*]] = and <2 x i16> [[NSB4]], splat (i16 2048) 137; CHECK-NEXT: [[ADD11:%.*]] = add nsw <2 x i16> [[AND11]], [[NSB4]] 138; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD11]]) 139; CHECK-NEXT: ret void 140; 141 %ashr = ashr <2 x i8> %x, <i8 5, i8 5> 142 %zext = zext <2 x i8> %ashr to <2 x i16> 143 %nsb4 = shl <2 x i16> %zext, <i16 10, i16 10> 144 ; Validate ComputeNumSignBits using this simplification: 145 ; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit 146 ; 4 sign bits: Goal is to fold away the add for bits 12-14. 147 %and14 = and <2 x i16> %nsb4, <i16 16384, i16 16384> 148 %add14 = add <2 x i16> %and14, %nsb4 149 call void @escape2(<2 x i16> %add14) 150 %and13 = and <2 x i16> %nsb4, <i16 8192, i16 8192> 151 %add13 = add <2 x i16> %and13, %nsb4 152 call void @escape2(<2 x i16> %add13) 153 %and12 = and <2 x i16> %nsb4, <i16 4096, i16 4096> 154 %add12 = add <2 x i16> %and12, %nsb4 155 call void @escape2(<2 x i16> %add12) 156 %and11 = and <2 x i16> %nsb4, <i16 2048, i16 2048> 157 %add11 = add <2 x i16> %and11, %nsb4 158 call void @escape2(<2 x i16> %add11) 159 ret void 160} 161