| 
80 | 80 | exit:  | 
81 | 81 |   ret void  | 
82 | 82 | }  | 
 | 83 | + | 
 | 84 | +; Same as above, except one zext is replaced with an sext.  | 
 | 85 | +define void @opcode_mismatch(ptr %dst.start, i8 %a, i16 %b) {  | 
 | 86 | +; CHECK-LABEL: define void @opcode_mismatch(  | 
 | 87 | +; CHECK-SAME: ptr [[DST_START:%.*]], i8 [[A:%.*]], i16 [[B:%.*]]) {  | 
 | 88 | +; CHECK-NEXT:  [[ENTRY:.*:]]  | 
 | 89 | +; CHECK-NEXT:    br label %[[VECTOR_PH:.*]]  | 
 | 90 | +; CHECK:       [[VECTOR_PH]]:  | 
 | 91 | +; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i16> poison, i16 [[B]], i64 0  | 
 | 92 | +; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i16> [[BROADCAST_SPLATINSERT]], <4 x i16> poison, <4 x i32> zeroinitializer  | 
 | 93 | +; CHECK-NEXT:    [[BROADCAST_SPLATINSERT1:%.*]] = insertelement <4 x i8> poison, i8 [[A]], i64 0  | 
 | 94 | +; CHECK-NEXT:    [[BROADCAST_SPLAT2:%.*]] = shufflevector <4 x i8> [[BROADCAST_SPLATINSERT1]], <4 x i8> poison, <4 x i32> zeroinitializer  | 
 | 95 | +; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]  | 
 | 96 | +; CHECK:       [[VECTOR_BODY]]:  | 
 | 97 | +; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]  | 
 | 98 | +; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 4  | 
 | 99 | +; CHECK-NEXT:    [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[DST_START]], i64 [[OFFSET_IDX]]  | 
 | 100 | +; CHECK-NEXT:    [[WIDE_VEC:%.*]] = load <16 x i8>, ptr [[NEXT_GEP]], align 1  | 
 | 101 | +; CHECK-NEXT:    [[STRIDED_VEC:%.*]] = shufflevector <16 x i8> [[WIDE_VEC]], <16 x i8> poison, <4 x i32> <i32 0, i32 4, i32 8, i32 12>  | 
 | 102 | +; CHECK-NEXT:    [[STRIDED_VEC3:%.*]] = shufflevector <16 x i8> [[WIDE_VEC]], <16 x i8> poison, <4 x i32> <i32 1, i32 5, i32 9, i32 13>  | 
 | 103 | +; CHECK-NEXT:    [[STRIDED_VEC4:%.*]] = shufflevector <16 x i8> [[WIDE_VEC]], <16 x i8> poison, <4 x i32> <i32 2, i32 6, i32 10, i32 14>  | 
 | 104 | +; CHECK-NEXT:    [[STRIDED_VEC5:%.*]] = shufflevector <16 x i8> [[WIDE_VEC]], <16 x i8> poison, <4 x i32> <i32 3, i32 7, i32 11, i32 15>  | 
 | 105 | +; CHECK-NEXT:    [[TMP0:%.*]] = zext <4 x i8> [[STRIDED_VEC]] to <4 x i16>  | 
 | 106 | +; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw <4 x i16> [[TMP0]], [[BROADCAST_SPLAT]]  | 
 | 107 | +; CHECK-NEXT:    [[TMP2:%.*]] = udiv <4 x i16> [[TMP1]], splat (i16 255)  | 
 | 108 | +; CHECK-NEXT:    [[TMP3:%.*]] = trunc nuw <4 x i16> [[TMP2]] to <4 x i8>  | 
 | 109 | +; CHECK-NEXT:    [[TMP4:%.*]] = add <4 x i8> [[BROADCAST_SPLAT2]], [[TMP3]]  | 
 | 110 | +; CHECK-NEXT:    store <4 x i8> [[TMP4]], ptr [[NEXT_GEP]], align 1  | 
 | 111 | +; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 1  | 
 | 112 | +; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], 64  | 
 | 113 | +; CHECK-NEXT:    br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]  | 
 | 114 | +; CHECK:       [[MIDDLE_BLOCK]]:  | 
 | 115 | +; CHECK-NEXT:    br label %[[EXIT:.*]]  | 
 | 116 | +; CHECK:       [[EXIT]]:  | 
 | 117 | +; CHECK-NEXT:    ret void  | 
 | 118 | +;  | 
 | 119 | +entry:  | 
 | 120 | +  br label %loop  | 
 | 121 | + | 
 | 122 | +loop:  | 
 | 123 | +  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]  | 
 | 124 | +  %dst = phi ptr [ %dst.start, %entry ], [ %dst.next, %loop ]  | 
 | 125 | +  %dst.next = getelementptr inbounds nuw i8, ptr %dst, i64 4  | 
 | 126 | +  %load.dst = load i8, ptr %dst, align 1  | 
 | 127 | +  %dst.ext = zext i8 %load.dst to i16  | 
 | 128 | +  %mul.dst.0 = mul nuw i16 %dst.ext, %b  | 
 | 129 | +  %udiv.0 = udiv i16 %mul.dst.0, 255  | 
 | 130 | +  %trunc.0 = trunc nuw i16 %udiv.0 to i8  | 
 | 131 | +  %val.0 = add i8 %a, %trunc.0  | 
 | 132 | +  store i8 %val.0, ptr %dst, align 1  | 
 | 133 | +  %gep.dst.1 = getelementptr inbounds nuw i8, ptr %dst, i64 1  | 
 | 134 | +  %load.dst.1 = load i8, ptr %gep.dst.1, align 1  | 
 | 135 | +  %dst.1.ext = sext i8 %load.dst.1 to i16  | 
 | 136 | +  %mul.dst.1 = mul nuw i16 %dst.1.ext, %b  | 
 | 137 | +  %udiv.1 = udiv i16 %mul.dst.1, 255  | 
 | 138 | +  %trunc.1 = trunc nuw i16 %udiv.1 to i8  | 
 | 139 | +  %val.1 = add i8 %a, %trunc.1  | 
 | 140 | +  store i8 %val.1, ptr %gep.dst.1, align 1  | 
 | 141 | +  %gep.dst.2 = getelementptr inbounds nuw i8, ptr %dst, i64 2  | 
 | 142 | +  %load.dst.2 = load i8, ptr %gep.dst.2, align 1  | 
 | 143 | +  %dst.2.ext = zext i8 %load.dst.2 to i16  | 
 | 144 | +  %mul.dst.2 = mul nuw i16 %dst.2.ext, %b  | 
 | 145 | +  %udiv.2 = udiv i16 %mul.dst.2, 255  | 
 | 146 | +  %trunc.2 = trunc nuw i16 %udiv.2 to i8  | 
 | 147 | +  %val.2 = add i8 %a, %trunc.2  | 
 | 148 | +  store i8 %val.2, ptr %gep.dst.2, align 1  | 
 | 149 | +  %gep.dst.3 = getelementptr inbounds nuw i8, ptr %dst, i64 3  | 
 | 150 | +  %load.dst.3 = load i8, ptr %gep.dst.3, align 1  | 
 | 151 | +  %dst.3.ext = zext i8 %load.dst.3 to i16  | 
 | 152 | +  %mul.dst.3 = mul nuw i16 %dst.3.ext, %b  | 
 | 153 | +  %udiv.3 = udiv i16 %mul.dst.3, 255  | 
 | 154 | +  %trunc.3 = trunc nuw i16 %udiv.3 to i8  | 
 | 155 | +  %val.3 = add i8 %a, %trunc.3  | 
 | 156 | +  store i8 %val.3, ptr %gep.dst.3, align 1  | 
 | 157 | +  %iv.next = add i64 %iv, 4  | 
 | 158 | +  %exit.cond = icmp eq i64 %iv.next, 256  | 
 | 159 | +  br i1 %exit.cond, label %exit, label %loop  | 
 | 160 | + | 
 | 161 | +exit:  | 
 | 162 | +  ret void  | 
 | 163 | +}  | 
0 commit comments