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