https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114682
Bug ID: 114682 Summary: const_array[i].b where i is PHI<0,1,2> is not folded Product: gcc Version: 14.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: enhancement Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: pinskia at gcc dot gnu.org Target Milestone: --- Take: ``` #include <cstddef> typedef struct cts_mode_name2id_st { unsigned int id; const char *name; } CTS_MODE_NAME2ID; /* The value assigned to 0 is the default */ #define CTS_CS1 0 #define CTS_CS2 1 #define CTS_CS3 2 /* OSSL_CIPHER_PARAM_CTS_MODE Values */ # define OSSL_CIPHER_CTS_MODE_CS1 "CS1" # define OSSL_CIPHER_CTS_MODE_CS2 "CS2" # define OSSL_CIPHER_CTS_MODE_CS3 "CS3" static CTS_MODE_NAME2ID cts_modes[] = { { CTS_CS1, OSSL_CIPHER_CTS_MODE_CS1 }, { CTS_CS2, OSSL_CIPHER_CTS_MODE_CS2 }, { CTS_CS3, OSSL_CIPHER_CTS_MODE_CS3 }, }; #define OSSL_NELEM(a) (sizeof(a)/sizeof(a[0])) int OPENSSL_strcasecmp(const char*, const char*); int ossl_cipher_cbc_cts_mode_name2id(const char *name) { size_t i; for (i = 0; i < OSSL_NELEM(cts_modes); ++i) { if (OPENSSL_strcasecmp(name, cts_modes[i].name) == 0) return (int)cts_modes[i].id; } return -1; } ``` We end up with the following in the .optimized at -O2 or -O3: ``` # i_3 = PHI <2(4), 0(2), 1(3)> _2 = cts_modes[i_3].id; _12 = (int) _2; ``` But cts_modes[i_3].id here is could be constant folded by the compiler into the same constants as i really. I suspect it is because we don't have a PRE post unrolling pass which could handle that. This shows up in openssl https://github.com/openssl/openssl/blob/master/providers/implementations/ciphers/cipher_cts.c#L55