<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/83268>83268</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[IndVarSimplify] WRONG code with i128 and -replexitval=always
</td>
</tr>
<tr>
<th>Labels</th>
<td>
miscompilation,
loopoptim
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
JonPsson1
</td>
</tr>
</table>
<pre>
This program should print -86:
```
int printf(const char *, ...);
unsigned short a = 0, b = 0;
unsigned __int128 c = 0, d = 0;
unsigned char e(unsigned char f, unsigned char g) { return f + g; }
long h() {
for (; c != 2; c = e(c, 3)) {
--d;
if (d)
continue;
return a;
}
return b;
}
int main() {
h();
printf("%d\n", (int)d);
}
```
With the option -replexitval=always, the IndVarSimplifyPass does something quite weird that I don't understand. It seems it is trying to compute the final value that is stored in the preheader, but that computation is '0', so it must be wrong.
`clang -O3 -march=z15 wrong0.i -o ./a.out <> clang -O3 -march=z15 wrong0.i -o ./a.out -mllvm -replexitval=always
`
```
IR Dump After IndVarSimplifyPass on for.body
define dso_local i64 @h() local_unnamed_addr #1 { define dso_local i64 @h() local_unnamed_addr #1 {
entry: entry:
%.pr = load i128, ptr @c, align 8, !tbaa !4 %.pr = load i128, ptr @c, align 8, !tbaa !4
%d.promoted = load i128, ptr @d, align 1, !tbaa !4 %d.promoted = load i128, ptr @d, align 1, !tbaa !4
%cmp.not5 = icmp eq i128 %.pr, 2 %cmp.not5 = icmp eq i128 %.pr, 2
%extract.t9 = trunc i128 %.pr to i8 %extract.t9 = trunc i128 %.pr to i8
br i1 %cmp.not5, label %return, label %for.body.prehea br i1 %cmp.not5, label %return, label %for.body.prehea
for.body.preheader: ; pred for.body.preheader: ; pred
> %0 = add i128 %d.promoted, -1
> %1 = mul i8 %extract.t9, 85
> %2 = add i8 %1, 85
> %3 = zext i8 %2 to i128
> %umin = call i128 @llvm.umin.i128(i128 %0, i128 %3)
> %4 = sub i128 %0, %umin
br label %for.body br label %for.body
for.body: ; pred for.body: ; pred
%.off0 = phi i8 [ %add.i, %for.inc ], [ %extract.t9, % %.off0 = phi i8 [ %add.i, %for.inc ], [ %extract.t9, %
%dec46 = phi i128 [ %dec, %for.inc ], [ %d.promoted, % %dec46 = phi i128 [ %dec, %for.inc ], [ %d.promoted, %
%dec = add i128 %dec46, -1 %dec = add i128 %dec46, -1
%tobool.not = icmp eq i128 %dec, 0 %tobool.not = icmp eq i128 %dec, 0
br i1 %tobool.not, label %for.body.return_crit_edge, l br i1 %tobool.not, label %for.body.return_crit_edge, l
for.inc: ; pred for.inc: ; pred
%add.i = add i8 %.off0, 3 %add.i = add i8 %.off0, 3
%conv2 = zext i8 %add.i to i128 %conv2 = zext i8 %add.i to i128
store i128 %conv2, ptr @c, align 8, !tbaa !4 store i128 %conv2, ptr @c, align 8, !tbaa !4
%cmp.not = icmp eq i8 %add.i, 2 %cmp.not = icmp eq i8 %add.i, 2
br i1 %cmp.not, label %for.cond.return_crit_edge, labe br i1 %cmp.not, label %for.cond.return_crit_edge, labe
for.cond.return_crit_edge: ; pred for.cond.return_crit_edge: ; pred
%dec.lcssa10 = phi i128 [ %dec, %for.inc ] | store i128 %4, ptr @d, align 8, !tbaa !4
store i128 %dec.lcssa10, ptr @d, align 8, !tbaa !4 <
br label %return br label %return
for.body.return_crit_edge: ; pred for.body.return_crit_edge: ; pred
%dec.lcssa = phi i128 [ %dec, %for.body ] | store i128 %4, ptr @d, align 8, !tbaa !4
store i128 %dec.lcssa, ptr @d, align 8, !tbaa !4 <
br label %return br label %return
return: ; pred return: ; pred
%retval.0.in.in = phi ptr [ @a, %for.body.return_crit_ %retval.0.in.in = phi ptr [ @a, %for.body.return_crit_
%retval.0.in = load i16, ptr %retval.0.in.in, align 2, %retval.0.in = load i16, ptr %retval.0.in.in, align 2,
%retval.0 = zext i16 %retval.0.in to i64 %retval.0 = zext i16 %retval.0.in to i64
ret i64 %retval.0 ret i64 %retval.0
} }
;
```
@nikic @xortator @uweigand
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0WF2TojgX_jXx5pQUBFC88KK7ffut3oudqdmtnUsrJFGyCwmThP6YX7-VgAiK0_Y4a3W1Ep7znO9DCDFG7CXna5Teo3QzI40tlF7_puRnY5SMZrlib-s_C2Gg1mqvSQWmUE3JoNZCWphnCxTfoXCDwsP_Rdj9-UsH8tAdwhlV0ligBdGA8B3CDxAEAcIrFN8PKRrpjWJOlbZAAMUbCB08734e8D1yuxXSRjgDegSzE_CJiDeDI5yNV3ZOdLy0R3gFaHkPmttGS9gBwvewR_E9oOVmSF4quYcC4ayTaFcBdsp5nDkJCghHzjDcXcUbbwV1emMXjLEowHzOeh_ctXD6M-ag_RoAVdIK2fARtDOYDBZ7i_u7-TFCY29c7ioi5Lk_nYsD2j7HCGOEU4bSB-l_PjhjhbQIr9go1b2uccF8FbYAW3BQtRVKwlzzuuSvwj6TEsUbUr6QN-NoHeZJsr-I_kNUdSl2b5-JMcAUN2BUxW0h5B6-NcJyeOFCM7AFsfAETEmElxYaybg2lkgWwJMFw3llQFgQBqx-c8JWAVVV3Vjute2EJCU8k7LhLZcwYKzSnIGQHlFrXnDCuPbF2tgW1nIQ744wgPAyRHjpIEY5hVVjLOQcXrSS--CkmWhJ5B7mn2KYV0TTAsWb71HaYsNAwFxBgPAjCVRjXcpR_IDi_wF8SG5eleVzdSHWfZYud_nTF9g0VQ13O8v1VFaUdD0QuGkypGF8JyQHZtS2VJSUIBYJoCQ8tJBf3DZSkoqzLWHMtVEc-Wa8QbZVzqXVbyi-g8OPvkVwGtTad2apCAMROcYHqK12CnynklLsJWRtfUc2J8R9JzD1uYFvYBILaq0qZTm7yMSOTNGZZbdTDIyhVR1IZVPPI2hVA__mqTpnnSieDMY4LlfxDPTyV6sJtYFdeQmrG0mHeNeyIrseeaDONYhoaJBTXJKcl26xHZSjpUM1B23LH526lWnYHie33FyJ794LanzvxhA7XN_C0UXHz5MuYaGPJmGsj-WxqJxb82hCKPJCVVOe5caJZOmECD7q8SLRRWTskd_5q-2g2KfWlfU5uKmE9HhKyrJzIQnd8AvcraDthuzgm99HHC7i4xN3SJl4PtPkMJLqlA0K7Czjk4tT-XcZu5TX4b3hAFO7XZuruhA-MOm9WyeMBaKzz1EISQGlG7_SIsbJQTgdD7JfxzucbZwmiyOrj2MrxTj9Ieu4-k6t_YW8Y2vPu8BpahvgneYaWfcjnkOt4dSqXKnSTZPJOdn5Er6r8Eqes6F4lJueXO1U21It7JazPfeoo-bbeE4bQkh6qR-6W1d_JvrG1_HJ7PE177fn7yOGz0gln_HpcGqluwF1HepA6beaY7kbdiU_z3a-DRhXUzaaB_ha3KVH8VmpUCXZdKmQnE9U3U_xnFbdNPhCHV4EX1-HjNOgpMaQKLx-fp3SLh9O0pxM7_QupngsPbDpSp7ev4ep5-Dh_fNsaXIPdG3w3wVPRfmKGPsn9nmQ_7sofyzGt0W5W5kI6fmdQfw0d6-KQRi4rZPsg-itdjFMQnISwVFmfgHFtDHD15tFH8dTZceg-tF3DOTNXBNWDUZ8tDhV4Sb9IvkgfHCMcyb9sc8EQ39IMzji6o9uxi__3f8klOIfQV3GXpW2xCpfus0LF3siGczYOmareEVmfB0tw1UUR1Eazop1stgts4jEyyXhOIlznC2Wy3TFc8oXYZ6nM7HGIU5CjLMoiVdRGDCM0yUlKxphkoUsQknIKyLKwG_kld7PhDENX2cxXmQzX_bGn3BiXAlDVVWL0h_HtCdUCONSqVrVVlRuJd3M9NpRzfNmb9z7gTDWHMmtsKU_MR0fdLjZ8PXLp9__D1QxDi_CFm1TO-8nj1ZmjS7XhbW1QfEdwo8IP-6FLZo8oKpC-NFp7L7mtVZ_c2oRfvS-GYQfvXv_BgAA___x6f_c">