Message ID | CANeU7Q=VPubjUkjWP20Ye8rA8d42OfVD=xM1U-quVqGK4kQb+g@mail.gmail.com (mailing list archive) |
---|---|
State | Mainlined, archived |
Headers | show |
Hi Chris, On 13 November 2017 at 15:28, Christopher Li <sparse@chrisli.org> wrote: > Currently value pseudo does not have size. > This create a problem pointed out by Dibyendu. > When using LLVM, calling varidic function with > constant value, there is no where to find the > size. > > Linus give out two suggestions. One is give pseudo > a size. The other one is the push instruction. > This is the implementation of the first suggestion. I tested out this change in my code base and it seems fine. I hope this helps. Thanks and Regards Dibyendu -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sun, Dec 24, 2017 at 9:10 PM, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote: > > I tested out this change in my code base and it seems fine. I hope this helps. > Thanks you so much for testing this branch. It is good to know that it works for you. Sorry for the late reply. Chris -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 13 November 2017 at 15:28, Christopher Li <sparse@chrisli.org> wrote: > Currently value pseudo does not have size. > This create a problem pointed out by Dibyendu. > When using LLVM, calling varidic function with > constant value, there is no where to find the > size. > > Linus give out two suggestions. One is give pseudo > a size. The other one is the push instruction. > This is the implementation of the first suggestion. > > The model is actual very simple. The pseudo is > exactly as before if you are not looking at the size. > There is a size at create time, which tag alone with > it. > Chris, I think the discussion of this topic should be moved to this thread. I found a problem with this as I mentioned in the other thread. Last year a change was introduced to initialize aggregate structures in Sparse using a store instruction that uses a PSEUDO_VAL. However when this creates a pseudo the size is set to the size of the aggregate types - and this size (> 64 bits) is kind of nonsensical for a PSEUDO_VAL. I suggested that when creating a PSEUDO_VAL we should only create distinct values when size is register size - i.e. one of 8, 16, 32, or 64. Else we should set size to 0. Couple of more points: a) We should also set size to 0 when we create a PSEUDO_VAL in CSE for uninitialized vars. b) We should ideally avoid CSE on PSEUDO_VAL with size = 0 because I don't think it makes sense to do so - i.e. they either represent uninitialized vars or aggregates > 64 bits. The above aggregate initialization change is one of the changes I did not merge into my project as I wasn't happy with it. I still think this change is not correct and needs to be removed or redone. I am not 100% sure but presumably creating PSEUDO_VAL where the instruction size is > 64-bits means that these PSEUDO_VAL values might be considered 'same as' any other PSEUDO_VAL with value 0. Thanks and Regards Dibyendu -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 3 March 2018 at 21:26, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote: > On 13 November 2017 at 15:28, Christopher Li <sparse@chrisli.org> wrote: >> Currently value pseudo does not have size. >> This create a problem pointed out by Dibyendu. >> When using LLVM, calling varidic function with >> constant value, there is no where to find the >> size. >> >> Linus give out two suggestions. One is give pseudo >> a size. The other one is the push instruction. >> This is the implementation of the first suggestion. >> >> The model is actual very simple. The pseudo is >> exactly as before if you are not looking at the size. >> There is a size at create time, which tag alone with >> it. >> > > Chris, I think the discussion of this topic should be moved to this thread. > > I found a problem with this as I mentioned in the other thread. Last > year a change was introduced to initialize aggregate structures in > Sparse using a store instruction that uses a PSEUDO_VAL. However when > this creates a pseudo the size is set to the size of the aggregate > types - and this size (> 64 bits) is kind of nonsensical for a > PSEUDO_VAL. > > I suggested that when creating a PSEUDO_VAL we should only create > distinct values when size is register size - i.e. one of 8, 16, 32, or > 64. Else we should set size to 0. > > Couple of more points: > > a) We should also set size to 0 when we create a PSEUDO_VAL in CSE for > uninitialized vars. > b) We should ideally avoid CSE on PSEUDO_VAL with size = 0 because I > don't think it makes sense to do so - i.e. they either represent > uninitialized vars or aggregates > 64 bits. > > The above aggregate initialization change is one of the changes I did > not merge into my project as I wasn't happy with it. I still think > this change is not correct and needs to be removed or redone. I am not > 100% sure but presumably creating PSEUDO_VAL where the instruction > size is > 64-bits means that these PSEUDO_VAL values might be > considered 'same as' any other PSEUDO_VAL with value 0. > Forgot to add a simple example from my test pack: struct foo { long long int i,j; }; extern void dosomething(struct foo *foo); int main(void) { struct foo bar = { 99 }; dosomething(&bar); return 0; } Here you will see a PESUDO_VAL with value 0 being created with size 16 bytes. Regards -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 3 March 2018 at 21:42, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote: > On 3 March 2018 at 21:26, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote: >> On 13 November 2017 at 15:28, Christopher Li <sparse@chrisli.org> wrote: >>> Currently value pseudo does not have size. >>> This create a problem pointed out by Dibyendu. >>> When using LLVM, calling varidic function with >>> constant value, there is no where to find the >>> size. >>> >>> Linus give out two suggestions. One is give pseudo >>> a size. The other one is the push instruction. >>> This is the implementation of the first suggestion. >>> >>> The model is actual very simple. The pseudo is >>> exactly as before if you are not looking at the size. >>> There is a size at create time, which tag alone with >>> it. >>> >> >> Chris, I think the discussion of this topic should be moved to this thread. >> >> I found a problem with this as I mentioned in the other thread. Last >> year a change was introduced to initialize aggregate structures in >> Sparse using a store instruction that uses a PSEUDO_VAL. However when >> this creates a pseudo the size is set to the size of the aggregate >> types - and this size (> 64 bits) is kind of nonsensical for a >> PSEUDO_VAL. >> >> I suggested that when creating a PSEUDO_VAL we should only create >> distinct values when size is register size - i.e. one of 8, 16, 32, or >> 64. Else we should set size to 0. >> >> Couple of more points: >> >> a) We should also set size to 0 when we create a PSEUDO_VAL in CSE for >> uninitialized vars. >> b) We should ideally avoid CSE on PSEUDO_VAL with size = 0 because I >> don't think it makes sense to do so - i.e. they either represent >> uninitialized vars or aggregates > 64 bits. >> >> The above aggregate initialization change is one of the changes I did >> not merge into my project as I wasn't happy with it. I still think >> this change is not correct and needs to be removed or redone. I am not >> 100% sure but presumably creating PSEUDO_VAL where the instruction >> size is > 64-bits means that these PSEUDO_VAL values might be >> considered 'same as' any other PSEUDO_VAL with value 0. >> > > Forgot to add a simple example from my test pack: > > struct foo { > long long int i,j; > }; > > extern void dosomething(struct foo *foo); > > int main(void) > { > struct foo bar = { 99 }; > dosomething(&bar); > return 0; > } > > Here you will see a PESUDO_VAL with value 0 being created with size 16 bytes. > In case you are wondering where this is happening - look at: static pseudo_t linearize_one_symbol(struct entrypoint *ep, struct symbol *sym) { struct access_data ad = { NULL, }; pseudo_t value; if (!sym || !sym->initializer || sym->initialized) return VOID; /* We need to output these puppies some day too.. */ if (sym->ctype.modifiers & (MOD_STATIC | MOD_TOPLEVEL)) return VOID; sym->initialized = 1; ad.address = symbol_pseudo(ep, sym); if (sym->initializer && !is_scalar_type(sym)) { // default zero initialization [6.7.9.21] // FIXME: this init the whole aggregate while // only the existing fields need to be initialized. // FIXME: this init the whole aggregate even if // all fields arelater explicitely initialized. struct expression *expr = sym->initializer; ad.pos = expr->pos; ad.result_type = sym; ad.source_type = base_type(sym); ad.address = symbol_pseudo(ep, sym); linearize_store_gen(ep, value_pseudo(sym, 0), &ad); } value = linearize_initializer(ep, sym->initializer, &ad); finish_address_gen(ep, &ad); return value; } -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi, Almost a year ago I had reported a problem with Sparse simplification phase. https://marc.info/?l=linux-sparse&m=148953605610758&w=2 Given below is a test program. With the release Sparse 0.5.1 release, the output from test-linearizer is: cbrtl: ep 0x7f5a27050010: cbrtl .L0: bug1.c:1 <entry-point> set.64 %r4 <- 0.000000 ret.64 %r4 Now I had a hunch that the bug may be resolved when PSEUDO_VALs have a size. So I tried the same program with Chris' git repo version. The output is: cbrtl: .L0x7f4c4c3b0010: <entry-point> set.64 %r1 <- 1.000000 set.64 %r4 <- 0.000000 ret.64 %r4 Hurray! I think some of the bugs in Sparse simplification phase is because all PSEUDO_VALs with same value are considered equal - irrespective of size! Here is the test: double cbrtl (double x) { int hx; double r,s,w; double lt; unsigned sign; union { double t; unsigned pt[2]; } ut, ux; int n0; ut.t = 1.0; n0 = (ut.pt[0] == 0); ut.t = 0.0; ux.t = x; return ut.t; } Regards -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 5 March 2018 at 21:21, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote: > Hi, > > Almost a year ago I had reported a problem with Sparse simplification phase. > > https://marc.info/?l=linux-sparse&m=148953605610758&w=2 > > Given below is a test program. > > With the release Sparse 0.5.1 release, the output from test-linearizer is: > > cbrtl: > ep 0x7f5a27050010: cbrtl > > .L0: > bug1.c:1 > <entry-point> > set.64 %r4 <- 0.000000 > ret.64 %r4 > > Now I had a hunch that the bug may be resolved when PSEUDO_VALs have a > size. So I tried the same program with Chris' git repo version. > > The output is: > > cbrtl: > .L0x7f4c4c3b0010: > <entry-point> > set.64 %r1 <- 1.000000 > set.64 %r4 <- 0.000000 > ret.64 %r4 > > Hurray! > > I think some of the bugs in Sparse simplification phase is because all > PSEUDO_VALs with same value are considered equal - irrespective of > size! > > Here is the test: > > double cbrtl (double x) > { > int hx; > double r,s,w; > double lt; > unsigned sign; > union { > double t; > unsigned pt[2]; > } ut, ux; > int n0; > ut.t = 1.0; > n0 = (ut.pt[0] == 0); > ut.t = 0.0; > ux.t = x; > return ut.t; > } > Apologies looks like my example above is wrong (i.e. does not reflect the original issue) ... please ignore. Regards -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 5 March 2018 at 21:32, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote: > On 5 March 2018 at 21:21, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote: >> Hi, >> >> Almost a year ago I had reported a problem with Sparse simplification phase. >> >> https://marc.info/?l=linux-sparse&m=148953605610758&w=2 >> >> Given below is a test program. >> >> With the release Sparse 0.5.1 release, the output from test-linearizer is: >> >> cbrtl: >> ep 0x7f5a27050010: cbrtl >> >> .L0: >> bug1.c:1 >> <entry-point> >> set.64 %r4 <- 0.000000 >> ret.64 %r4 >> >> Now I had a hunch that the bug may be resolved when PSEUDO_VALs have a >> size. So I tried the same program with Chris' git repo version. >> >> The output is: >> >> cbrtl: >> .L0x7f4c4c3b0010: >> <entry-point> >> set.64 %r1 <- 1.000000 >> set.64 %r4 <- 0.000000 >> ret.64 %r4 >> >> Hurray! >> >> I think some of the bugs in Sparse simplification phase is because all >> PSEUDO_VALs with same value are considered equal - irrespective of >> size! >> >> Here is the test: >> >> double cbrtl (double x) >> { >> int hx; >> double r,s,w; >> double lt; >> unsigned sign; >> union { >> double t; >> unsigned pt[2]; >> } ut, ux; >> int n0; >> ut.t = 1.0; >> n0 = (ut.pt[0] == 0); >> ut.t = 0.0; >> ux.t = x; >> return ut.t; >> } >> > > Apologies looks like my example above is wrong (i.e. does not reflect > the original issue) ... please ignore. > The actual test is: https://github.com/dibyendumajumdar/sparse-testing/blob/master/eic/testcbrt.c. I messed it up by trying to shorten it. Here is the first few lines of output from Sparse 0.5.1: cbrtl: .L0: <entry-point> load.32 %r2 <- 0[ut] seteq.32 %r3 <- %r2, $0 set.64 %r4 <- 0.000000 store.64 %r4 -> 0[ut] store.64 %arg1 -> 0[ux] And here is the output from Chris version: cbrtl: .L0x7f29db910010: <entry-point> set.64 %r1 <- 1.000000 load.32 %r2 <- 0[ut] seteq.32 %r3 <- %r2, $0 set.64 %r4 <- 0.000000 store.64 %r4 -> 0[ut] store.64 %arg1 -> 0[ux] And here is the output from dmr_C: cbrtl: .L0: <entry-point> set.f64 %r1 <- 1.000000 store.f64 %r1 -> 0[ut] load.32 %r2 <- 0[ut] seteq.32 %r3 <- %r2, $0 set.f64 %r4 <- 0.000000 store.f64 %r4 -> 0[ut] store.f64 %arg1 -> 0[ux] So the problem still seems to be there I think :-( Regards Dibyendu -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
I am trying to test this change ... and work out the impact. It seems interesting to create some weird examples: struct A { long x,y; }; struct B { char buf[100]; union { int j; long long k; } u; }; extern int printf(const char *, ...); void bar(int j) { printf("got %d\n", j); } void foo() { struct A a = { 0 }; struct B b = { { 0 } }; a.y == 0 ? bar(1) : bar(0); b.u.j == 0 ? bar(1) : bar(0); b.u.k == 0 ? bar(1) : bar(0); } int main(void) { foo(); return 0; } Now the output from Chris' version is: bar: .L0x7f0d5f810010: <entry-point> call.32 %r3 <- printf, "got %d\n", %arg1 ret foo: .L0x7f0d5f8100b0: <entry-point> call bar, $1 call bar, $1 call bar, $1 ret main: .L0x7f0d5f810420: <entry-point> call foo ret.32 $0 And the output from Sparse 0.5.1 is: bar: .L0: <entry-point> call.32 %r3 <- printf, "got %d\n", %arg1 ret foo: .L2: <entry-point> store.128 $0 -> 0[a] store.64 $0 -> 0[a] store.896 $0 -> 0[b] store.8 $0 -> 0[b] load.64 %r4 <- 8[a] cbr %r4, .L4, .L3 .L3: call bar, $1 br .L5 .L4: call bar, $0 br .L5 .L5: load.32 %r7 <- 104[b] cbr %r7, .L7, .L6 .L6: call bar, $1 br .L8 .L7: call bar, $0 br .L8 .L8: load.64 %r10 <- 104[b] cbr %r10, .L10, .L9 .L9: call bar, $1 br .L12 .L10: call bar, $0 br .L12 .L12: ret main: .L13: <entry-point> call foo ret.32 $0 -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/flow.c b/flow.c index 6b2c879a..fa5d31c8 100644 --- a/flow.c +++ b/flow.c @@ -517,7 +517,7 @@ found: if (!local) return 0; check_access(insn); - convert_load_instruction(insn, value_pseudo(0)); + convert_load_instruction(insn, value_pseudo(insn->type, 0)); return 1; } diff --git a/linearize.c b/linearize.c index ba76397e..2aa3acb2 100644 --- a/linearize.c +++ b/linearize.c @@ -785,22 +785,25 @@ static pseudo_t symbol_pseudo(struct entrypoint *ep, struct symbol *sym) return pseudo; } -pseudo_t value_pseudo(long long val) +pseudo_t value_pseudo(struct symbol *type, long long val) { #define MAX_VAL_HASH 64 static struct pseudo_list *prev[MAX_VAL_HASH]; int hash = val & (MAX_VAL_HASH-1); struct pseudo_list **list = prev + hash; + int size = type ? type->bit_size : value_size(val); pseudo_t pseudo; + FOR_EACH_PTR(*list, pseudo) { - if (pseudo->value == val) + if (pseudo->value == val && pseudo->size == size) return pseudo; } END_FOR_EACH_PTR(pseudo); pseudo = __alloc_pseudo(0); pseudo->type = PSEUDO_VAL; pseudo->value = val; + pseudo->size = size; add_pseudo(list, pseudo); /* Value pseudos have neither nr, usage nor def */ @@ -954,10 +957,10 @@ static pseudo_t linearize_store_gen(struct entrypoint *ep, unsigned long long mask = (1ULL << size) - 1; if (shift) { - store = add_binary_op(ep, ad->source_type, OP_SHL, value, value_pseudo(shift)); + store = add_binary_op(ep, ad->source_type, OP_SHL, value, value_pseudo(ctype, shift)); mask <<= shift; } - orig = add_binary_op(ep, ad->source_type, OP_AND, orig, value_pseudo(~mask)); + orig = add_binary_op(ep, ad->source_type, OP_AND, orig, value_pseudo(ctype, ~mask)); store = add_binary_op(ep, ad->source_type, OP_OR, orig, store); } add_store(ep, ad, store); @@ -1002,7 +1005,7 @@ static pseudo_t linearize_load_gen(struct entrypoint *ep, struct access_data *ad pseudo_t new = add_load(ep, ad); if (ctype->bit_offset) { - pseudo_t shift = value_pseudo(ctype->bit_offset); + pseudo_t shift = value_pseudo(ctype, ctype->bit_offset); pseudo_t newval = add_binary_op(ep, ad->source_type, OP_LSR, new, shift); new = newval; } @@ -1034,7 +1037,7 @@ static pseudo_t linearize_inc_dec(struct entrypoint *ep, struct expression *expr return VOID; old = linearize_load_gen(ep, &ad); - one = value_pseudo(expr->op_value); + one = value_pseudo(expr->ctype, expr->op_value); new = add_binary_op(ep, expr->ctype, op, old, one); linearize_store_gen(ep, new, &ad); finish_address_gen(ep, &ad); @@ -1073,7 +1076,7 @@ static pseudo_t linearize_regular_preop(struct entrypoint *ep, struct expression case '+': return pre; case '!': { - pseudo_t zero = value_pseudo(0); + pseudo_t zero = value_pseudo(expr->ctype, 0); return add_binary_op(ep, expr->ctype, OP_SET_EQ, pre, zero); } case '~': @@ -1165,7 +1168,7 @@ static inline pseudo_t add_convert_to_bool(struct entrypoint *ep, pseudo_t src, if (is_bool_type(type)) return src; - zero = value_pseudo(0); + zero = value_pseudo(type, 0); op = OP_SET_NE; return add_binary_op(ep, &bool_ctype, op, src, zero); } @@ -1591,7 +1594,7 @@ pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr) return add_symbol_address(ep, expr->symbol); case EXPR_VALUE: - return value_pseudo(expr->value); + return value_pseudo(expr->ctype, expr->value); case EXPR_STRING: case EXPR_FVALUE: case EXPR_LABEL: return add_setval(ep, expr->ctype, expr); @@ -1681,7 +1684,7 @@ static pseudo_t linearize_one_symbol(struct entrypoint *ep, struct symbol *sym) ad.result_type = sym; ad.source_type = base_type(sym); ad.address = symbol_pseudo(ep, sym); - linearize_store_gen(ep, value_pseudo(0), &ad); + linearize_store_gen(ep, value_pseudo(sym, 0), &ad); } value = linearize_initializer(ep, sym->initializer, &ad); diff --git a/linearize.h b/linearize.h index bac82d7f..fd8e00d3 100644 --- a/linearize.h +++ b/linearize.h @@ -32,7 +32,10 @@ struct pseudo { int nr; enum pseudo_type type; struct pseudo_user_list *users; - struct ident *ident; + union { + struct ident *ident; + int size; /* OP_SETVAL only */ + }; union { struct symbol *sym; struct instruction *def; @@ -333,7 +336,8 @@ extern void insert_branch(struct basic_block *bb, struct instruction *br, struct pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, int size); pseudo_t alloc_pseudo(struct instruction *def); -pseudo_t value_pseudo(long long val); +pseudo_t value_pseudo(struct symbol *type, long long val); +unsigned int value_size(long long value); struct entrypoint *linearize_symbol(struct symbol *sym); int unssa(struct entrypoint *ep); diff --git a/memops.c b/memops.c index aeacdf56..6a795c19 100644 --- a/memops.c +++ b/memops.c @@ -127,7 +127,7 @@ static void simplify_loads(struct basic_block *bb) if (!dominators) { if (local) { assert(pseudo->type != PSEUDO_ARG); - convert_load_instruction(insn, value_pseudo(0)); + convert_load_instruction(insn, value_pseudo(insn->type, 0)); } goto next_load; } diff --git a/simplify.c b/simplify.c index 2bc86f53..1e926e7d 100644 --- a/simplify.c +++ b/simplify.c @@ -352,7 +352,7 @@ static int replace_with_pseudo(struct instruction *insn, pseudo_t pseudo) return REPEAT_CSE; } -static unsigned int value_size(long long value) +unsigned int value_size(long long value) { value >>= 8;
Currently value pseudo does not have size. This create a problem pointed out by Dibyendu. When using LLVM, calling varidic function with constant value, there is no where to find the size. Linus give out two suggestions. One is give pseudo a size. The other one is the push instruction. This is the implementation of the first suggestion. The model is actual very simple. The pseudo is exactly as before if you are not looking at the size. There is a size at create time, which tag alone with it. I might not get all the type and cast of the constant right, we can fix it later if we found some case I did not cover. Testing done: - Test suite passed. - Kernel compile get the exact same output as the RC5 at similar time. Reported-by: Dibyendu Majumdar <mobile@majumdar.org.uk> Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Christopher Li <sparse@chrisli.org> --- flow.c | 2 +- linearize.c | 23 +++++++++++++---------- linearize.h | 8 ++++++-- memops.c | 2 +- simplify.c | 20 ++++++++++---------- 5 files changed, 31 insertions(+), 24 deletions(-) if (!value) @@ -398,7 +398,7 @@ static int simplify_asr(struct instruction *insn, pseudo_t pseudo, long long val if (value >= size) { warning(insn->pos, "right shift by bigger than source value"); - return replace_with_pseudo(insn, value_pseudo(0)); + return replace_with_pseudo(insn, value_pseudo(insn->type, 0)); } if (!value) return replace_with_pseudo(insn, pseudo); @@ -508,7 +508,7 @@ static int simplify_constant_rightside(struct instruction *insn) case OP_SUB: if (value) { insn->opcode = OP_ADD; - insn->src2 = value_pseudo(-value); + insn->src2 = value_pseudo(insn->type, -value); return REPEAT_CSE; } /* Fall through */ @@ -525,7 +525,7 @@ static int simplify_constant_rightside(struct instruction *insn) case OP_MODU: case OP_MODS: if (value == 1) - return replace_with_pseudo(insn, value_pseudo(0)); + return replace_with_pseudo(insn, value_pseudo(insn->type, 0)); return 0; case OP_DIVU: case OP_DIVS: @@ -686,7 +686,7 @@ static int simplify_constant_binop(struct instruction *insn) } res &= bits; - replace_with_pseudo(insn, value_pseudo(res)); + replace_with_pseudo(insn, value_pseudo(insn->type, res)); return REPEAT_CSE; } @@ -700,14 +700,14 @@ static int simplify_binop_same_args(struct instruction *insn, pseudo_t arg) warning(insn->pos, "self-comparison always evaluates to false"); case OP_SUB: case OP_XOR: - return replace_with_pseudo(insn, value_pseudo(0)); + return replace_with_pseudo(insn, value_pseudo(insn->type, 0)); case OP_SET_EQ: case OP_SET_LE: case OP_SET_GE: case OP_SET_BE: case OP_SET_AE: if (Wtautological_compare) warning(insn->pos, "self-comparison always evaluates to true"); - return replace_with_pseudo(insn, value_pseudo(1)); + return replace_with_pseudo(insn, value_pseudo(insn->type, 1)); case OP_AND: case OP_OR: @@ -716,7 +716,7 @@ static int simplify_binop_same_args(struct instruction *insn, pseudo_t arg) case OP_AND_BOOL: case OP_OR_BOOL: remove_usage(arg, &insn->src2); - insn->src2 = value_pseudo(0); + insn->src2 = value_pseudo(insn->type, 0); insn->opcode = OP_SET_NE; return REPEAT_CSE; @@ -819,7 +819,7 @@ static int simplify_constant_unop(struct instruction *insn) mask = 1ULL << (insn->size-1); res &= mask | (mask-1); - replace_with_pseudo(insn, value_pseudo(res)); + replace_with_pseudo(insn, value_pseudo(insn->type, res)); return REPEAT_CSE; } @@ -952,7 +952,7 @@ static int simplify_cast(struct instruction *insn) if (constant(src)) { int sign = orig_type->ctype.modifiers & MOD_SIGNED; long long val = get_cast_value(src->value, orig_size, size, sign); - src = value_pseudo(val); + src = value_pseudo(orig_type, val); goto simplify; }