<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/85535>85535</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[InstCombine] WRONG code with sroa-skip-mem2reg
</td>
</tr>
<tr>
<th>Labels</th>
<td>
miscompilation,
llvm:instcombine
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
JonPsson1
</td>
</tr>
</table>
<pre>
It seems that InstCombiner is incorrectly replacing a sext with a zext (see '<>' below):
```
left : clang -O3 -march=z16 wrong0.i -o a.out -fno-unroll-loops -mllvm -unroll-full-max-count=1 -fno-vectorize -fno-slp-vectorize
right: clang -O3 -march=z16 wrong0.i -o a.out -fno-unroll-loops -mllvm -unroll-full-max-count=1 -fno-vectorize -fno-slp-vectorize -mllvm -sroa-skip-mem2reg
```
```
; *** IR Dump After InstCombinePass on main *** ; *** IR Dump After InstCombinePass on main ***
; Function Attrs: nounwind ; Function Attrs: nounwind
define dso_local signext i32 @main() local_unnamed_addr | define dso_local signext i32 @main() local_unnamed_addr
entry: entry:
%0 = load ptr, ptr @IntVar1Ptr, align 8, !tbaa !13 %0 = load ptr, ptr @IntVar1Ptr, align 8, !tbaa !13
store i32 -7, ptr %0, align 4, !tbaa !4 store i32 -7, ptr %0, align 4, !tbaa !4
%.pr.i = load i16, ptr @ShortIV, align 2, !tbaa !8 | %1 = load i16, ptr @ShortIV, align 2, !tbaa !8
%cmp.i = icmp sgt i16 %.pr.i, -1 | %cmp.i = icmp sgt i16 %1, -1
br i1 %cmp.i, label %for.cond.i, label %for.body11.lr. | br i1 %cmp.i, label %for.cond.us.i, label %for.cond.i,
for.cond.i: ; pred | for.cond.us.i: ; pred
br label %for.cond.i | br label %for.cond.us.i
for.body11.lr.ph.i: ; pred | for.cond.i: ; pred
%IntVar2.promoted.i = load i32, ptr @IntVar2, align 1, | %2 = load ptr, ptr @ShortVar1Ptr, align 8, !tbaa !13
%1 = load ptr, ptr @ShortVar1Ptr, align 8, !tbaa !13 | %.pre.i = load i32, ptr @IntVar2, align 4, !tbaa !4
br label %for.body11.i br label %for.body11.i
for.body11.i: ; pred | for.body11.i: ; pred
%add2325.i = phi i32 [ %IntVar2.promoted.i, %for.body1 | %3 = phi i32 [ %.pre.i, %for.cond.i ], [ %add.i, %for.
%2 = load i32, ptr %0, align 4, !tbaa !4 | %4 = load i32, ptr %0, align 4, !tbaa !4
%3 = trunc i32 %2 to i8 | %5 = trunc i32 %4 to i8
%4 = or i8 %3, -8 | %6 = or i8 %5, -8
%mul.i.i = mul i8 %4, -36 | %conv14.i = mul nsw i8 %6, -36
>>%conv17.i = sext i8 %mul.i.i to i16 <> %conv17.i = zext nneg i8 %conv14.i to i16
store i16 %conv17.i, ptr %1, align 2, !tbaa !8 | store i16 %conv17.i, ptr %2, align 2, !tbaa !8
%add.i = add nsw i32 %add2325.i, 1 | %add.i = add nsw i32 %3, 1
store i32 %add.i, ptr @IntVar2, align 4, !tbaa !4 store i32 %add.i, ptr @IntVar2, align 4, !tbaa !4
%5 = load i16, ptr @ShortIV, align 2, !tbaa !8 | %7 = load i16, ptr @ShortIV, align 2, !tbaa !8
%inc18.i = add i16 %5, 1 | %inc18.i = add i16 %7, 1
store i16 %inc18.i, ptr @ShortIV, align 2, !tbaa !8 store i16 %inc18.i, ptr @ShortIV, align 2, !tbaa !8
%cmp9.not.i = icmp eq i16 %inc18.i, 0 %cmp9.not.i = icmp eq i16 %inc18.i, 0
br i1 %cmp9.not.i, label %fun.exit, label %for.body11. br i1 %cmp9.not.i, label %fun.exit, label %for.body11.
fun.exit: ; pred fun.exit: ; pred
%6 = load i16, ptr @ShortVar1, align 2, !tbaa !8 | %8 = load i16, ptr @ShortVar1, align 2, !tbaa !8
%7 = lshr i16 %6, 8 | %9 = lshr i16 %8, 8
%conv1 = zext nneg i16 %7 to i32 | %conv1 = zext nneg i16 %9 to i32
store i32 %conv1, ptr @Val, align 4, !tbaa !4 store i32 %conv1, ptr @Val, align 4, !tbaa !4
%call = call signext i32 (ptr, ...) @printf(ptr nounde %call = call signext i32 (ptr, ...) @printf(ptr nounde
ret i32 0 ret i32 0
} }
```
```
cat wrong0.i
int printf(const char *, ...);
int Val, IntVar1, IntVar2;
short ShortVar1;
short ShortIV = -1;
short *ShortVar1Ptr = &ShortVar1;
int *IntVar1Ptr = &IntVar1;
unsigned char safeMul(unsigned char si1, unsigned char si2) { return si1 * si2; }
void setVal(char b) { Val = b; }
void fun(int Arg) { // -4
long LongLoc;
signed char CharArr[1][3][2];
for (; ShortIV >= 0;)
CharArr[0][2][1]++;
signed char *CharElPtr = &CharArr[0][2][1];
for (; ShortIV != 0; ShortIV++) {
LongLoc = ((((unsigned)*IntVar1Ptr) | 0x5a915f8) * 9) & 0x7fffffffffffffff;
*CharElPtr = ((unsigned char) (((unsigned long) LongLoc) & 0xff));
*ShortVar1Ptr = ((signed char) safeMul(((unsigned int) (Arg & 0xff)), *CharElPtr));
IntVar2 += 1;
}
}
int main() {
*IntVar1Ptr = -7;
fun(-4);
setVal(ShortVar1 >> 8);
printf("checksum = %X\n", Val);
}
```
? @dtcxzyw @nikic
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEWdtv4ywW_2vIC7Jl4_iShzykTbvq6tv9RrNSd99GxCYJOxi8gNvO_PUrwBfsOJ1eRvqiqHbh8Du_c4NjBytFT5yQLUhvQLpf4Vafhdz-XfAvSgkerw6i-rF90FARUiuoz1jDB670ragPlBMJqYKUl0JKUmr2A0rSMFxSfoIYKvKi4TPVZ4jhT3MPUKEIgQDlILkFyR1AOTwQJp4B2oBkB6I9iPq_WdR97b-MHDUEyQ6WDPMTDP5MYFBjWZ5Bsv8ZZ_BZCn6KQgoDAXEoWg2DIxdBy6VgLGBCNAoGNWNPNewHjy1jQY1fglK0XINkH7s1T6TUQtKfxP2rWDMOOTKSns76ryczYCgpcKC-0yaoSY0kOS26cHkwuYEA7dwXPnyF-7Zu4O6oifTD_AUrBQWHNabck59_PoU2Erpveamp4HCntVTG0Vy0_JnyCr4-7SAqcqScwEqJb0yUmEGb4S8a0gRBsI6MWoAKgDbQzn9rOcc1qb7hqpLWjPzWXD6H47gQruUPQ7G_ccMQApRGECR7yASuYKMlQLfmYoAfuH7EMv7iBjGjJw4LcwtQrA8Ym2uc_AaInozSQhJrVpAPICiNxrXr2dr1Rez7zwewPJ-EjQzpaBSNM8-of52F1A-PIxKaIRV9HuZmOI0_DuRRKuumo0TLuoHqpA3aQNasDOKr7uhy6RdIsUPptB4kpPGwwEwxfCDMjByFDEvBq4Vhs1HHcchk6Kt9C1arXtPi7x7eRLKzxdhIUo36ppCeSO_Pg1zSctV7c08uLre6ZiRHZzTnX5K182_7zO0BKHWlhsJGilpoUk3yN0EXRYnGtLNhn-YIulbRNmffUdPT_P8Y1kUGh40k77DvaqXP49iFi16duBLfVyK7JOH5BlcVSlDaGdOcqdvV05vlkDpDRkrjJpMsATg_eYu6PAfp3g46KVxNkT16aNnH79yT_dCtP4LoMXJ2atny0llqSGoBaTFRk16KrZ2Yh-W4CGkXozSxu98UJ5uKpE7Ew6hbFtIufHXLOjlrQZBk031X8Kd47cly9dzJZ51833zc2a7Urci7FbaNdeK9UmNQnF3ZIUxnC-cgtv_lnJw6pIGTBzU7jt3R0KN4EYt_fQJOov8rPPS2g9CmqzUGV5XzoQvwUEtm8bWjsCuXqyA2CeLLjsSvkzfvMzPdn0TrSA3Z_ZnWZF6W-W_pUSgv48Lzaxfr1AXE13dFMl_yvpvqVnzU2N-ANm3GNiEX2u-jyP8WwKP3SXsH09AudUunnVHLQ_JC9bXua7T6s0iTE6-XfXOfAv1T0X4-g-EFIHs1X01P8Za08DOy-Ayix6yrJHWWfYAt2PRY2VwI2a5nkmJmg5zv2V2V2N06QdcdNj91lnE2HU6ndbI92WWeFx4xe99j2CfQfC9gxix5ezN58kVF102GYWgefsE6aiTl-uhm7NN4RTyn_Aa0npkkblk03nWFku8hyPevveqY_ltiPbyocSOUazioLgVXGpZnLN0bip4fSG58HWZN59PukXu8RYOsMpkMx3xeGH94tP4J5pMA7fxu3QoBlF1iGSYA7cYH_1605zUl3nIbhcqZqPCR_KNlABWzcWrtmQ8iG6j8xgShldyIGd12JrmZx-FJ0Aoqoq2fCgtx6AEescuLw7V1x5YDVBjjdvLUr4IA3QN0D4MhY5ngJ_iH4Kc_RDlYCqFP-_aM5U5KkN7Epg1PbxJ3QeYydY59gjCpaViN4bkzTCMjizad4AgaeWidCnRjvnNonxNAO4Nwx7x4vQo5mLZEEMU9QTgcqpaCc1tPAPaO6jQWw7ePs7HPTyUHcAujlxRv4vRo33mZgG_cTQajl_w4_XhRgEt2FvNkc1AzJjawZqaP7aDveLQsN3M9C9ViAGeKxoSf6aNcd0R28jRXZbfL0ZIFAl3lQxv4PRyrzkvuaZab1PbeJHpxuqzmIPeUucoI1hMKQ5kNbnB5e2ee7n2qw0YHECrPpPyu2rpzV_ofkN5ygOxha9G8XW8gv_hyObk3-3ely5efP57NLaffabmqtkm1STZ4RbZxHkdZhFCcr87b4lBkJItJiUkW5eiwLqI0JgdMSJ7nUYVXdIsitI6SOIvTOEvzMEsPeVHlmyqu0ixZr8E6IjWmLGTsqQ6FPK2oUi3ZFmmapCvbVyn70wZCNVWlqBvKsKaiMw8gZBaCZEe50qV7PW2m0v1Kbs1UcGhPCqwjRpVWoxZNNbO_mXivtUG6h__--uc__wZLURH3w8fFq_lVK9n2rHWjQLJz29iJ6nN7CEtRA3Rv6bhL0EjxX1JqgO6tUQqge2vX_wMAAP___4X1aQ">