------- Additional Comments From rsandifo at gcc dot gnu dot org 2005-07-04 13:49 ------- Are you sure this reduced testcase is an accurate reflection of the real one? The transformation performed by gcc appears to be correct. For example, r00450DB4 evaluates to 0, so anything ANDed with it does too.
Here's an attempt to show why. I've snipped part of the code and annotated it with comments of the form: <rhs> = op (<lhs>) :<nonzero bits> where <lhs> uses "_" for "don't care" values. <nonzero bits> is the mask of bits that _might_ be nonzero. In other words, zero bits mean "known to be zero" and one bits mean "value unknown". ------------------------------------------------------------------------------- UINT32 r004458AC = opt_and(w00, 0x5A827999); // A = and (_, cst) :5a827999 UINT32 r00445934 = opt_and(r004457EC, r004458AC); // B = and (_, A) :5a827999 UINT32 r004459BC = opt_and(r0044572C, r00445934); // C = and (_, B) :5a827999 ... UINT32 r0044F67C = opt_and(ie, r004459BC); // D = and (_, C) :5a827999 ... UINT32 r0044FA14 = opt_rotl(r0044F67C, 5); // E = rotl (D, 5) :504f332b UINT32 r0044FAD4 = opt_and(w01, 0x5A827999); // F = and (_, cst) :5a827999 UINT32 r0044FB5C = opt_and(r0044FA14, r0044FAD4); // G = and (E, F) :50023109 UINT32 r0044FBE4 = opt_and(r0044F954, r0044FB5C); // H = and (_, G) :50023109 UINT32 r0044FC6C = opt_and(id, r0044FBE4); // I = and (_, H) :50023109 ... UINT32 r00450004 = opt_rotl(r0044FC6C, 5); // J = rotl (I, 5) :0046212a UINT32 r004500C4 = opt_and(w02, 0x5A827999); // K = and (_, cst) :5a827999 UINT32 r0045014C = opt_and(r00450004, r004500C4); // L = and (J, K) :00022108 UINT32 r004501D4 = opt_and(r0044FF44, r0045014C); // M = and (_, L) :00022108 UINT32 r0045025C = opt_and(ic, r004501D4); // N = and (_, M) :00022108 ... UINT32 r0045031C = opt_rotl(r0044F67C, 30); // a = rotl (D, 30) :56a09e66 ... UINT32 r004505F4 = opt_rotl(r0045025C, 5); // O = rotl (N, 5) :00442100 UINT32 r004506B4 = opt_and(w03, 0x5A827999); // P = and (_, cst) :5a827999 UINT32 r0045073C = opt_and(r004505F4, r004506B4); // Q = and (O, P) :00002100 UINT32 r004507C4 = opt_and(r00450534, r0045073C); // R = and (_, Q) :00002100 UINT32 r0045084C = opt_and(r0044F73C, r004507C4); // S = and (_, R) :00002100 UINT32 r0045090C = opt_rotl(r0044FC6C, 30); // T = rotl (I, 30) :54008c42 UINT32 r00450994 = opt_not(r0045025C); // b = not (N) :fffddef7 UINT32 r00450A14 = opt_and(r00450994, r0045031C); // c = and (b, a) :56a09e66 ... UINT32 r00450A9C = opt_and(r0045025C, r0045090C); // U = and (N, T) :00000000 UINT32 r00450B24 = opt_or(r00450A14, r00450A9C); // V = or (c, U) :56a09e66 UINT32 r00450BE4 = opt_rotl(r0045084C, 5); // W = rotl (S, 5) :00042000 UINT32 r00450CA4 = opt_and(w04, 0x5A827999); // X = and (_, cst) :5a827999 UINT32 r00450D2C = opt_and(r00450BE4, r00450CA4); // Y = and (W, X) :00002000 UINT32 r00450DB4 = opt_and(r00450B24, r00450D2C); // Z = and (V, Y) :00000000 ------------------------------------------------------------------------------- PS. Not that it matters for the code quoted above, but your opt_xor function uses "+" instead of "^". -- What |Removed |Added ---------------------------------------------------------------------------- CC| |rsandifo at gcc dot gnu dot | |org Status|NEW |WAITING http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21970