Here is a source code:
bool EXITFLAG = false;
int originfunc() {
unsigned long x, y;
x = dosomething();
y = dosomething();
{
signed char xx = x, yy = y;
if ((xx) >= (unsigned char)(yy) )
EXITFLAG = true;
}
return 0;
}
It generate IR like this:
define i32 @originfunc() #0 {
entry:
%call = call i64 @dosomething()
%call1 = call i64 @dosomething()
%conv = trunc i64 %call to i8
%conv2 = trunc i64 %call1 to i8
%conv3 = sext i8 %conv to i32
%conv4 = zext i8 %conv2 to i32
%cmp = icmp sge i32 %conv3, %conv4
br i1 %cmp, label %if.then, label %if.end
....
}
My question is about the trunc and sext/zext.
In InstCombiner::visitSExt, sext is changed into shl + ashr, and change the result type of trunc before, the result is like this:
%call = call i64 @random_bitstring()
%call1 = call i64 @random_bitstring()
%conv = trunc i64 %call to i32
%conv2 = trunc i64 %call1 to i32
%sext = shl i32 %conv, 24
%conv3 = ashr exact i32 %sext, 24
%conv4 = and i32 %conv2, 255
%cmp.not = icmp slt i32 %conv3, %conv4
The DAG of trunc and sext/zext is like:
t10: i32 = truncate t5
t14: i32 = shl t10, Constant:i64<24>
t15: i32 = sra exact t14, Constant:i64<24>
t11: i32 = truncate t9
t17: i32 = and t11, Constant:i32<255>
The type i8 seems to be eliminated.
But in the after stage, fold (sra (shl x, c1), c1) → sext_inreg, I get DAG like this:
t10: i32 = truncate t5
t26: i32 = sign_extend_inreg t10, ValueType:ch:i8
t11: i32 = truncate t9
t17: i32 = and t11, Constant:i32<255>
The problem is here, the source type of t26 become i8 again, not match the type of t10 before. Is this reasonable?