Message ID | 20211219200630.2325031-1-hjl.tools@gmail.com |
---|---|
State | New |
Headers | show |
Series | ix86: Don't match the 'm' constraint on x86_64_general_operand | expand |
On Sun, Dec 19, 2021 at 9:06 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > x86_64_general_operand is different from general_operand for 64-bit > target. To avoid LRA selecting a memory operand which doesn't satisfy > x86_64_general_operand for 64-bit target: > > 1. Add a 'BM' constraint which is similar to the 'm' constraint, but > checks x86_64_general_operand for integers > 16 bits. > 2. Replace the 'm' constraint on x86_64_general_operand with the 'BM' > constraint. > > gcc/ > > PR target/103762 > * config/i386/constraints.md (BM): New constraint. > * config/i386/i386.md: Replace the 'm' constraint on > x86_64_general_operand with the 'BM' constraint. > * config/i386/predicates.md (ix86_memory_operand): New predicate. > > gcc/testsuite/ > > * gcc.target/i386/pr103762-1a.c: New test. > * gcc.target/i386/pr103762-1b.c: Likewise. > * gcc.target/i386/pr103762-1c.c: Likewise. > --- > gcc/config/i386/constraints.md | 5 + > gcc/config/i386/i386.md | 64 +- > gcc/config/i386/predicates.md | 6 + > gcc/testsuite/gcc.target/i386/pr103762-1a.c | 647 ++++++++++++++++++++ > gcc/testsuite/gcc.target/i386/pr103762-1b.c | 7 + > gcc/testsuite/gcc.target/i386/pr103762-1c.c | 7 + > 6 files changed, 704 insertions(+), 32 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/i386/pr103762-1a.c > create mode 100644 gcc/testsuite/gcc.target/i386/pr103762-1b.c > create mode 100644 gcc/testsuite/gcc.target/i386/pr103762-1c.c > > diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md > index 6b291a02d88..6677285e518 100644 > --- a/gcc/config/i386/constraints.md > +++ b/gcc/config/i386/constraints.md > @@ -168,6 +168,7 @@ > ;; z Constant call address operand. > ;; C Integer SSE constant with all bits set operand. > ;; F Floating-point SSE constant with all bits set operand. > +;; M ix86 memory operand. > > (define_constraint "Bf" > "@internal Flags register operand." > @@ -232,6 +233,10 @@ > (and (match_test "TARGET_SSE") > (match_operand 0 "float_vector_all_ones_operand"))) > > +(define_constraint "BM" > + "@internal ix86 memory operand." > + (match_operand 0 "ix86_memory_operand")) > + > ;; Integer constant constraints. > (define_constraint "Wb" > "Integer constant in the range 0 @dots{} 7, for 8-bit shifts." > diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md > index d25453fe574..4f30819a1d9 100644 > --- a/gcc/config/i386/i386.md > +++ b/gcc/config/i386/i386.md > @@ -1385,7 +1385,7 @@ > (define_insn "*cmp<mode>_1" > [(set (reg FLAGS_REG) > (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") > - (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))] > + (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>BM")))] > "ix86_match_ccmode (insn, CCmode)" > "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" > [(set_attr "type" "icmp") > @@ -1395,7 +1395,7 @@ > [(set (reg FLAGS_REG) > (compare > (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") > - (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")) > + (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>BM")) > (const_int 0)))] > "ix86_match_ccmode (insn, CCGOCmode)" > "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" > @@ -5653,7 +5653,7 @@ > [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r") > (plus:SWI48 > (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r") > - (match_operand:SWI48 2 "x86_64_general_operand" "re,m,0,le"))) > + (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le"))) > (clobber (reg:CC FLAGS_REG))] > "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" > { > @@ -5709,7 +5709,7 @@ > [(set (match_operand:DI 0 "register_operand" "=r,r,r") > (zero_extend:DI > (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r") > - (match_operand:SI 2 "x86_64_general_operand" "rme,0,le")))) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le")))) > (clobber (reg:CC FLAGS_REG))] > "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" > { > @@ -5967,7 +5967,7 @@ > (compare > (plus:SWI > (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>") > - (match_operand:SWI 2 "<general_operand>" "<r><i>,m,0")) > + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM,0")) > (const_int 0))) > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>") > (plus:SWI (match_dup 1) (match_dup 2)))] > @@ -6012,7 +6012,7 @@ > [(set (reg FLAGS_REG) > (compare > (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") > - (match_operand:SI 2 "x86_64_general_operand" "rme,0")) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe,0")) > (const_int 0))) > (set (match_operand:DI 0 "register_operand" "=r,r") > (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] > @@ -6097,7 +6097,7 @@ > (define_insn "*addsi_3_zext" > [(set (reg FLAGS_REG) > (compare > - (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0")) > + (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0")) > (match_operand:SI 1 "nonimmediate_operand" "%0,r"))) > (set (match_operand:DI 0 "register_operand" "=r,r") > (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] > @@ -6801,7 +6801,7 @@ > [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") > (minus:SWI > (match_operand:SWI 1 "nonimmediate_operand" "0,0") > - (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) > + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM"))) > (clobber (reg:CC FLAGS_REG))] > "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" > "sub{<imodesuffix>}\t{%2, %0|%0, %2}" > @@ -6812,7 +6812,7 @@ > [(set (match_operand:DI 0 "register_operand" "=r") > (zero_extend:DI > (minus:SI (match_operand:SI 1 "register_operand" "0") > - (match_operand:SI 2 "x86_64_general_operand" "rme")))) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) > (clobber (reg:CC FLAGS_REG))] > "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" > "sub{l}\t{%2, %k0|%k0, %2}" > @@ -6844,7 +6844,7 @@ > (compare > (minus:SWI > (match_operand:SWI 1 "nonimmediate_operand" "0,0") > - (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) > + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM")) > (const_int 0))) > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") > (minus:SWI (match_dup 1) (match_dup 2)))] > @@ -6858,7 +6858,7 @@ > [(set (reg FLAGS_REG) > (compare > (minus:SI (match_operand:SI 1 "register_operand" "0") > - (match_operand:SI 2 "x86_64_general_operand" "rme")) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) > (const_int 0))) > (set (match_operand:DI 0 "register_operand" "=r") > (zero_extend:DI > @@ -7111,7 +7111,7 @@ > (define_insn "*sub<mode>_3" > [(set (reg FLAGS_REG) > (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0") > - (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) > + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM"))) > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") > (minus:SWI (match_dup 1) (match_dup 2)))] > "ix86_match_ccmode (insn, CCmode) > @@ -7187,7 +7187,7 @@ > (define_insn "*subsi_3_zext" > [(set (reg FLAGS_REG) > (compare (match_operand:SI 1 "register_operand" "0") > - (match_operand:SI 2 "x86_64_general_operand" "rme"))) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe"))) > (set (match_operand:DI 0 "register_operand" "=r") > (zero_extend:DI > (minus:SI (match_dup 1) > @@ -7207,7 +7207,7 @@ > (match_operator:SWI 4 "ix86_carry_flag_operator" > [(match_operand 3 "flags_reg_operand") (const_int 0)]) > (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) > - (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) > + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM"))) > (clobber (reg:CC FLAGS_REG))] > "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" > "adc{<imodesuffix>}\t{%2, %0|%0, %2}" > @@ -7251,7 +7251,7 @@ > (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator" > [(reg FLAGS_REG) (const_int 0)]) > (match_operand:SI 1 "register_operand" "%0")) > - (match_operand:SI 2 "x86_64_general_operand" "rme")))) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) > (clobber (reg:CC FLAGS_REG))] > "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" > "adc{l}\t{%2, %k0|%k0, %2}" > @@ -7377,7 +7377,7 @@ > (match_operand:SWI 1 "nonimmediate_operand" "0,0") > (match_operator:SWI 4 "ix86_carry_flag_operator" > [(match_operand 3 "flags_reg_operand") (const_int 0)])) > - (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) > + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM"))) > (clobber (reg:CC FLAGS_REG))] > "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" > "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" > @@ -7422,7 +7422,7 @@ > (match_operand:SI 1 "register_operand" "0") > (match_operator:SI 3 "ix86_carry_flag_operator" > [(reg FLAGS_REG) (const_int 0)])) > - (match_operand:SI 2 "x86_64_general_operand" "rme")))) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) > (clobber (reg:CC FLAGS_REG))] > "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" > "sbb{l}\t{%2, %k0|%k0, %2}" > @@ -7498,7 +7498,7 @@ > (define_insn "@sub<mode>3_carry_ccgz" > [(set (reg:CCGZ FLAGS_REG) > (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0") > - (match_operand:DWIH 2 "x86_64_general_operand" "rme") > + (match_operand:DWIH 2 "x86_64_general_operand" "rBMe") > (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))] > UNSPEC_SBB)) > (clobber (match_scratch:DWIH 0 "=r"))] > @@ -7585,7 +7585,7 @@ > (compare:CCC > (plus:SWI > (match_operand:SWI 1 "nonimmediate_operand" "%0,0") > - (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) > + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM")) > (match_dup 1))) > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") > (plus:SWI (match_dup 1) (match_dup 2)))] > @@ -7616,7 +7616,7 @@ > (compare:CCC > (plus:SI > (match_operand:SI 1 "nonimmediate_operand" "%0") > - (match_operand:SI 2 "x86_64_general_operand" "rme")) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) > (match_dup 1))) > (set (match_operand:DI 0 "register_operand" "=r") > (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] > @@ -7643,7 +7643,7 @@ > (compare:CCC > (plus:SWI > (match_operand:SWI 1 "nonimmediate_operand" "%0,0") > - (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) > + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM")) > (match_dup 2))) > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") > (plus:SWI (match_dup 1) (match_dup 2)))] > @@ -7657,7 +7657,7 @@ > (compare:CCC > (plus:SI > (match_operand:SI 1 "nonimmediate_operand" "%0") > - (match_operand:SI 2 "x86_64_general_operand" "rme")) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) > (match_dup 2))) > (set (match_operand:DI 0 "register_operand" "=r") > (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] > @@ -8001,7 +8001,7 @@ > [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r") > (mult:SWIM248 > (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0") > - (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr"))) > + (match_operand:SWIM248 2 "<general_operand>" "K,<i>,BMr"))) > (clobber (reg:CC FLAGS_REG))] > "!(MEM_P (operands[1]) && MEM_P (operands[2]))" > "@ > @@ -8037,7 +8037,7 @@ > [(set (match_operand:DI 0 "register_operand" "=r,r,r") > (zero_extend:DI > (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") > - (match_operand:SI 2 "x86_64_general_operand" "K,e,mr")))) > + (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr")))) > (clobber (reg:CC FLAGS_REG))] > "TARGET_64BIT > && !(MEM_P (operands[1]) && MEM_P (operands[2]))" > @@ -9711,7 +9711,7 @@ > [(set (match_operand:DI 0 "register_operand" "=r") > (zero_extend:DI > (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") > - (match_operand:SI 2 "x86_64_general_operand" "rme")))) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) > (clobber (reg:CC FLAGS_REG))] > "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" > "and{l}\t{%2, %k0|%k0, %2}" > @@ -9721,7 +9721,7 @@ > (define_insn "*and<mode>_1" > [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k") > (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k") > - (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L,k"))) > + (match_operand:SWI24 2 "<general_operand>" "r<i>,BM,L,k"))) > (clobber (reg:CC FLAGS_REG))] > "ix86_binary_operator_ok (AND, <MODE>mode, operands)" > "@ > @@ -9903,7 +9903,7 @@ > [(set (reg FLAGS_REG) > (compare (and:SI > (match_operand:SI 1 "nonimmediate_operand" "%0") > - (match_operand:SI 2 "x86_64_general_operand" "rme")) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) > (const_int 0))) > (set (match_operand:DI 0 "register_operand" "=r") > (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] > @@ -9946,7 +9946,7 @@ > [(set (reg FLAGS_REG) > (compare (and:SWI124 > (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") > - (match_operand:SWI124 2 "<general_operand>" "<r><i>,m")) > + (match_operand:SWI124 2 "<general_operand>" "<r><i>,BM")) > (const_int 0))) > (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>") > (and:SWI124 (match_dup 1) (match_dup 2)))] > @@ -10260,7 +10260,7 @@ > [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k") > (any_or:SWI248 > (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k") > - (match_operand:SWI248 2 "<general_operand>" "r<i>,m,k"))) > + (match_operand:SWI248 2 "<general_operand>" "r<i>,BM,k"))) > (clobber (reg:CC FLAGS_REG))] > "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" > "@ > @@ -10328,7 +10328,7 @@ > [(set (match_operand:DI 0 "register_operand" "=r") > (zero_extend:DI > (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") > - (match_operand:SI 2 "x86_64_general_operand" "rme")))) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) > (clobber (reg:CC FLAGS_REG))] > "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" > "<logic>{l}\t{%2, %k0|%k0, %2}" > @@ -10431,7 +10431,7 @@ > [(set (reg FLAGS_REG) > (compare (any_or:SWI > (match_operand:SWI 1 "nonimmediate_operand" "%0,0") > - (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) > + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM")) > (const_int 0))) > (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") > (any_or:SWI (match_dup 1) (match_dup 2)))] > @@ -10446,7 +10446,7 @@ > (define_insn "*<code>si_2_zext" > [(set (reg FLAGS_REG) > (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") > - (match_operand:SI 2 "x86_64_general_operand" "rme")) > + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) > (const_int 0))) > (set (match_operand:DI 0 "register_operand" "=r") > (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] > diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md > index 770e2f0c0dd..cfc0a50e239 100644 > --- a/gcc/config/i386/predicates.md > +++ b/gcc/config/i386/predicates.md > @@ -1199,6 +1199,12 @@ > (and (match_operand 0 "memory_operand") > (not (match_test "x86_extended_reg_mentioned_p (op)")))) > > +;; Return true if OP is a memory operand representable on ix86. > +(define_predicate "ix86_memory_operand" > + (and (match_operand 0 "memory_operand") > + (ior (match_test "mode == QImode || mode == HImode") > + (match_operand 0 "x86_64_general_operand")))) The "mode" variable represents the mode of the predicate, not the operand. Please introduce another mode attribute (perhaps "m") and define it like this: (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")]) Then you can define the "BM" constraint directly to x86_64_general_operand. Uros. > + > ;; Return true for RTX codes that force SImode address. > (define_predicate "SImode_address_operand" > (match_code "subreg,zero_extend,and")) > diff --git a/gcc/testsuite/gcc.target/i386/pr103762-1a.c b/gcc/testsuite/gcc.target/i386/pr103762-1a.c > new file mode 100644 > index 00000000000..c9e75bc12d8 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr103762-1a.c > @@ -0,0 +1,647 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -std=gnu11 -fgnu89-inline" } */ > +/* { dg-final { scan-assembler-not ".quad\[\\t \]+tunable_list" { target lp64 } } } */ > +/* { dg-final { scan-assembler-not ".long\[\\t \]+tunable_list" { target { ! lp64 } } } } */ > + > +typedef unsigned long int size_t; > +typedef long long int intmax_t; > +typedef unsigned long long int uintmax_t; > +typedef unsigned long long int uint64_t; > +typedef intmax_t tunable_num_t; > +typedef union > +{ > + tunable_num_t numval; > + const char *strval; > +} tunable_val_t; > +enum > +{ > + HWCAP_X86_SSE2 = 1 << 0, > + HWCAP_X86_64 = 1 << 1, > + HWCAP_X86_AVX512_1 = 1 << 2 > +}; > +typedef void (*tunable_callback_t) (tunable_val_t *); > +extern void *__minimal_malloc (size_t n) > + __attribute__ ((visibility ("hidden"))); > +extern int __libc_enable_secure __attribute__ ((section (".data.rel.ro"))); > +extern uint64_t _dl_strtoul (const char *, char **) > + __attribute__ ((visibility ("hidden"))); > +extern void _dl_fatal_printf (const char *fmt, ...) > + __attribute__ ((__format__ (__printf__, 1, 2), __noreturn__)); > +typedef enum > +{ > + glibc_rtld_nns, > + glibc_elision_skip_lock_after_retries, > + glibc_malloc_trim_threshold, > + glibc_malloc_perturb, > + glibc_cpu_x86_shared_cache_size, > + glibc_pthread_rseq, > + glibc_mem_tagging, > + glibc_elision_tries, > + glibc_elision_enable, > + glibc_malloc_hugetlb, > + glibc_cpu_x86_rep_movsb_threshold, > + glibc_malloc_mxfast, > + glibc_rtld_dynamic_sort, > + glibc_elision_skip_lock_busy, > + glibc_malloc_top_pad, > + glibc_cpu_x86_rep_stosb_threshold, > + glibc_cpu_x86_non_temporal_threshold, > + glibc_cpu_x86_shstk, > + glibc_pthread_stack_cache_size, > + glibc_cpu_hwcap_mask, > + glibc_malloc_mmap_max, > + glibc_elision_skip_trylock_internal_abort, > + glibc_malloc_tcache_unsorted_limit, > + glibc_cpu_x86_ibt, > + glibc_cpu_hwcaps, > + glibc_elision_skip_lock_internal_abort, > + glibc_malloc_arena_max, > + glibc_malloc_mmap_threshold, > + glibc_cpu_x86_data_cache_size, > + glibc_malloc_tcache_count, > + glibc_malloc_arena_test, > + glibc_pthread_mutex_spin_count, > + glibc_rtld_optional_static_tls, > + glibc_malloc_tcache_max, > + glibc_malloc_check, > +} tunable_id_t; > +typedef enum > +{ > + TUNABLE_TYPE_INT_32, > + TUNABLE_TYPE_UINT_64, > + TUNABLE_TYPE_SIZE_T, > + TUNABLE_TYPE_STRING > +} tunable_type_code_t; > +typedef struct > +{ > + tunable_type_code_t type_code; > + tunable_num_t min; > + tunable_num_t max; > +} tunable_type_t; > +typedef enum > +{ > + TUNABLE_SECLEVEL_SXID_ERASE = 0, > + TUNABLE_SECLEVEL_SXID_IGNORE = 1, > + TUNABLE_SECLEVEL_NONE = 2, > +} tunable_seclevel_t; > +struct _tunable > +{ > + const char name[42]; > + tunable_type_t type; > + tunable_val_t val; > + _Bool initialized; > + tunable_seclevel_t security_level; > + const char env_alias[23]; > +}; > +typedef struct _tunable tunable_t; > +extern _Bool unsigned_tunable_type (tunable_type_code_t t); > + > +static tunable_t tunable_list[] __attribute__ ((section (".data.rel.ro"))) = { > + { "glibc" > + "." > + "rtld" > + "." > + "nns", > + { TUNABLE_TYPE_SIZE_T, 1, 16 }, > + { .numval = 4 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "elision" > + "." > + "skip_lock_after_retries", > + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, > + { .numval = 3 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "malloc" > + "." > + "trim_threshold", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_IGNORE, > + "MALLOC_TRIM_THRESHOLD_" }, > + { "glibc" > + "." > + "malloc" > + "." > + "perturb", > + { TUNABLE_TYPE_INT_32, 0, 0xff }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_IGNORE, > + "MALLOC_PERTURB_" }, > + { "glibc" > + "." > + "cpu" > + "." > + "x86_shared_cache_size", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "pthread" > + "." > + "rseq", > + { TUNABLE_TYPE_INT_32, 0, 1 }, > + { .numval = 1 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "mem" > + "." > + "tagging", > + { TUNABLE_TYPE_INT_32, 0, 255 }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_IGNORE, > + { 0 } }, > + { "glibc" > + "." > + "elision" > + "." > + "tries", > + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, > + { .numval = 3 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "elision" > + "." > + "enable", > + { TUNABLE_TYPE_INT_32, 0, 1 }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "malloc" > + "." > + "hugetlb", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "cpu" > + "." > + "x86_rep_movsb_threshold", > + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "malloc" > + "." > + "mxfast", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_IGNORE, > + { 0 } }, > + { "glibc" > + "." > + "rtld" > + "." > + "dynamic_sort", > + { TUNABLE_TYPE_INT_32, 1, 2 }, > + { .numval = 2 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "elision" > + "." > + "skip_lock_busy", > + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, > + { .numval = 3 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "malloc" > + "." > + "top_pad", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_IGNORE, > + "MALLOC_TOP_PAD_" }, > + { "glibc" > + "." > + "cpu" > + "." > + "x86_rep_stosb_threshold", > + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, > + { .numval = 2048 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "cpu" > + "." > + "x86_non_temporal_threshold", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "cpu" > + "." > + "x86_shstk", > + { TUNABLE_TYPE_STRING, 0, 0 }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "pthread" > + "." > + "stack_cache_size", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + { .numval = 41943040 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "cpu" > + "." > + "hwcap_mask", > + { TUNABLE_TYPE_UINT_64, 0, (18446744073709551615UL) }, > + { .numval = (HWCAP_X86_64 | HWCAP_X86_AVX512_1) }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + "LD_HWCAP_MASK" }, > + { "glibc" > + "." > + "malloc" > + "." > + "mmap_max", > + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_IGNORE, > + "MALLOC_MMAP_MAX_" }, > + { "glibc" > + "." > + "elision" > + "." > + "skip_trylock_internal_abort", > + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, > + { .numval = 3 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "malloc" > + "." > + "tcache_unsorted_limit", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "cpu" > + "." > + "x86_ibt", > + { TUNABLE_TYPE_STRING, 0, 0 }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "cpu" > + "." > + "hwcaps", > + { TUNABLE_TYPE_STRING, 0, 0 }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "elision" > + "." > + "skip_lock_internal_abort", > + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, > + { .numval = 3 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "malloc" > + "." > + "arena_max", > + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_IGNORE, > + "MALLOC_ARENA_MAX" }, > + { "glibc" > + "." > + "malloc" > + "." > + "mmap_threshold", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_IGNORE, > + "MALLOC_MMAP_THRESHOLD_" }, > + { "glibc" > + "." > + "cpu" > + "." > + "x86_data_cache_size", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "malloc" > + "." > + "tcache_count", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "malloc" > + "." > + "arena_test", > + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_IGNORE, > + "MALLOC_ARENA_TEST" }, > + { "glibc" > + "." > + "pthread" > + "." > + "mutex_spin_count", > + { TUNABLE_TYPE_INT_32, 0, 32767 }, > + { .numval = 100 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "rtld" > + "." > + "optional_static_tls", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + { .numval = 512 }, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "malloc" > + "." > + "tcache_max", > + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + { 0 } }, > + { "glibc" > + "." > + "malloc" > + "." > + "check", > + { TUNABLE_TYPE_INT_32, 0, 3 }, > + {}, > + ((void *)0), > + TUNABLE_SECLEVEL_SXID_ERASE, > + "MALLOC_CHECK_" }, > +}; > +extern void __tunables_init (char **); > +extern void __tunables_print (void); > +extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t); > +extern void __tunable_set_val (tunable_id_t, tunable_val_t *, tunable_num_t *, > + tunable_num_t *); > +static __inline __attribute__ ((__always_inline__)) _Bool > +tunable_val_lt (tunable_num_t lhs, tunable_num_t rhs, _Bool unsigned_cmp) > +{ > + if (unsigned_cmp) > + return (uintmax_t)lhs < (uintmax_t)rhs; > + else > + return lhs < rhs; > +} > +static __inline __attribute__ ((__always_inline__)) _Bool > +tunable_val_gt (tunable_num_t lhs, tunable_num_t rhs, _Bool unsigned_cmp) > +{ > + if (unsigned_cmp) > + return (uintmax_t)lhs > (uintmax_t)rhs; > + else > + return lhs > rhs; > +} > +static __inline __attribute__ ((__always_inline__)) _Bool > +tunable_is_name (const char *orig, const char *envname) > +{ > + for (; *orig != '\0' && *envname != '\0'; envname++, orig++) > + if (*orig != *envname) > + break; > + if (*orig == '\0' && *envname == '=') > + return 1; > + else > + return 0; > +} > +static char * > +tunables_strdup (const char *in) > +{ > + size_t i = 0; > + while (in[i++] != '\0') > + ; > + char *out = __minimal_malloc (i + 1); > + if (out == ((void *)0)) > + _dl_fatal_printf ("failed to allocate memory to process tunables\n"); > + while (i-- > 0) > + out[i] = in[i]; > + return out; > +} > +static char ** > +get_next_env (char **envp, char **name, size_t *namelen, char **val, > + char ***prev_envp) > +{ > + while (envp != ((void *)0) && *envp != ((void *)0)) > + { > + char **prev = envp; > + char *envline = *envp++; > + int len = 0; > + while (envline[len] != '\0' && envline[len] != '=') > + len++; > + if (envline[len] == '\0') > + continue; > + *name = envline; > + *namelen = len; > + *val = &envline[len + 1]; > + *prev_envp = prev; > + return envp; > + } > + return ((void *)0); > +} > +static void > +do_tunable_update_val (tunable_t *cur, const tunable_val_t *valp, > + const tunable_num_t *minp, const tunable_num_t *maxp) > +{ > + tunable_num_t val, min, max; > + if (cur->type.type_code == TUNABLE_TYPE_STRING) > + { > + cur->val.strval = valp->strval; > + cur->initialized = 1; > + return; > + } > + _Bool unsigned_cmp = unsigned_tunable_type (cur->type.type_code); > + val = valp->numval; > + min = minp != ((void *)0) ? *minp : cur->type.min; > + max = maxp != ((void *)0) ? *maxp : cur->type.max; > + if (tunable_val_lt (min, cur->type.min, unsigned_cmp)) > + min = cur->type.min; > + if (tunable_val_gt (max, cur->type.max, unsigned_cmp)) > + max = cur->type.max; > + if (tunable_val_gt (min, max, unsigned_cmp)) > + { > + min = cur->type.min; > + max = cur->type.max; > + } > + if (tunable_val_lt (val, min, unsigned_cmp) > + || tunable_val_lt (max, val, unsigned_cmp)) > + return; > + cur->val.numval = val; > + cur->type.min = min; > + cur->type.max = max; > + cur->initialized = 1; > +} > +static void > +tunable_initialize (tunable_t *cur, const char *strval) > +{ > + tunable_val_t val; > + if (cur->type.type_code != TUNABLE_TYPE_STRING) > + val.numval = (tunable_num_t)_dl_strtoul (strval, ((void *)0)); > + else > + val.strval = strval; > + do_tunable_update_val (cur, &val, ((void *)0), ((void *)0)); > +} > +static void > +parse_tunables (char *tunestr, char *valstring) > +{ > + if (tunestr == ((void *)0) || *tunestr == '\0') > + return; > + char *p = tunestr; > + size_t off = 0; > + while (1) > + { > + char *name = p; > + size_t len = 0; > + while (p[len] != '=' && p[len] != ':' && p[len] != '\0') > + len++; > + if (p[len] == '\0') > + { > + if (__libc_enable_secure) > + tunestr[off] = '\0'; > + return; > + } > + if (p[len] == ':') > + { > + p += len + 1; > + continue; > + } > + p += len + 1; > + char *value = &valstring[p - tunestr]; > + len = 0; > + while (p[len] != ':' && p[len] != '\0') > + len++; > + for (size_t i = 0; i < sizeof (tunable_list) / sizeof (tunable_t); i++) > + { > + tunable_t *cur = &tunable_list[i]; > + if (tunable_is_name (cur->name, name)) > + { > + if (__libc_enable_secure) > + { > + if (cur->security_level != TUNABLE_SECLEVEL_SXID_ERASE) > + { > + if (off > 0) > + tunestr[off++] = ':'; > + const char *n = cur->name; > + while (*n != '\0') > + tunestr[off++] = *n++; > + tunestr[off++] = '='; > + for (size_t j = 0; j < len; j++) > + tunestr[off++] = value[j]; > + } > + if (cur->security_level != TUNABLE_SECLEVEL_NONE) > + break; > + } > + value[len] = '\0'; > + tunable_initialize (cur, value); > + break; > + } > + } > + if (p[len] != '\0') > + p += len + 1; > + } > +} > +void > +__tunables_init (char **envp) > +{ > + char *envname = ((void *)0); > + char *envval = ((void *)0); > + size_t len = 0; > + char **prev_envp = envp; > + while ((envp = get_next_env (envp, &envname, &len, &envval, &prev_envp)) > + != ((void *)0)) > + { > + if (tunable_is_name ("GLIBC_TUNABLES", envname)) > + { > + char *new_env = tunables_strdup (envname); > + if (new_env != ((void *)0)) > + parse_tunables (new_env + len + 1, envval); > + *prev_envp = new_env; > + continue; > + } > + for (int i = 0; i < sizeof (tunable_list) / sizeof (tunable_t); i++) > + { > + tunable_t *cur = &tunable_list[i]; > + const char *name = cur->env_alias; > + if (tunable_is_name (name, envname)) > + { > + tunable_initialize (cur, envval); > + break; > + } > + } > + } > +} > diff --git a/gcc/testsuite/gcc.target/i386/pr103762-1b.c b/gcc/testsuite/gcc.target/i386/pr103762-1b.c > new file mode 100644 > index 00000000000..391f51cf7f1 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr103762-1b.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-require-effective-target pie } */ > +/* { dg-options "-O2 -std=gnu11 -fgnu89-inline -fpie" } */ > +/* { dg-final { scan-assembler-not ".quad\[\\t \]+tunable_list" { target lp64 } } } */ > +/* { dg-final { scan-assembler-not ".long\[\\t \]+tunable_list" { target { ! lp64 } } } } */ > + > +#include "pr103762-1a.c" > diff --git a/gcc/testsuite/gcc.target/i386/pr103762-1c.c b/gcc/testsuite/gcc.target/i386/pr103762-1c.c > new file mode 100644 > index 00000000000..4667b06c171 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr103762-1c.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-require-effective-target fpic } */ > +/* { dg-options "-O2 -std=gnu11 -fgnu89-inline -fpic" } */ > +/* { dg-final { scan-assembler-not ".quad\[\\t \]+tunable_list" { target lp64 } } } */ > +/* { dg-final { scan-assembler-not ".long\[\\t \]+tunable_list" { target { ! lp64 } } } } */ > + > +#include "pr103762-1a.c" > -- > 2.33.1 >
On Sun, Dec 19, 2021 at 12:06:30PM -0800, H.J. Lu via Gcc-patches wrote: > --- a/gcc/config/i386/predicates.md > +++ b/gcc/config/i386/predicates.md > @@ -1199,6 +1199,12 @@ > (and (match_operand 0 "memory_operand") > (not (match_test "x86_extended_reg_mentioned_p (op)")))) > > +;; Return true if OP is a memory operand representable on ix86. > +(define_predicate "ix86_memory_operand" > + (and (match_operand 0 "memory_operand") > + (ior (match_test "mode == QImode || mode == HImode") > + (match_operand 0 "x86_64_general_operand")))) I must be missing something, but how can this work? x86_64_general_operand is: (define_predicate "x86_64_general_operand" (if_then_else (match_test "TARGET_64BIT") (ior (match_operand 0 "nonimmediate_operand") (match_operand 0 "x86_64_immediate_operand")) (match_operand 0 "general_operand"))) and so for non-immediates like MEMs it is just a normal memory_operand. Jakub
On Mon, Dec 20, 2021 at 6:53 AM Jakub Jelinek <jakub@redhat.com> wrote: > > On Sun, Dec 19, 2021 at 12:06:30PM -0800, H.J. Lu via Gcc-patches wrote: > > --- a/gcc/config/i386/predicates.md > > +++ b/gcc/config/i386/predicates.md > > @@ -1199,6 +1199,12 @@ > > (and (match_operand 0 "memory_operand") > > (not (match_test "x86_extended_reg_mentioned_p (op)")))) > > > > +;; Return true if OP is a memory operand representable on ix86. > > +(define_predicate "ix86_memory_operand" > > + (and (match_operand 0 "memory_operand") > > + (ior (match_test "mode == QImode || mode == HImode") > > + (match_operand 0 "x86_64_general_operand")))) > > I must be missing something, but how can this work? > x86_64_general_operand is: > (define_predicate "x86_64_general_operand" > (if_then_else (match_test "TARGET_64BIT") > (ior (match_operand 0 "nonimmediate_operand") > (match_operand 0 "x86_64_immediate_operand")) > (match_operand 0 "general_operand"))) > and so for non-immediates like MEMs it is just a normal memory_operand. > > Jakub > The problem is in (define_memory_constraint "TARGET_MEM_CONSTRAINT" "Matches any valid memory." (and (match_code "mem") (match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0), MEM_ADDR_SPACE (op))"))) define_register_constraint allows LRA to convert the operand to the form '(mem (reg X))', where X is a base register. I am testing the v2 patch with ;; NB: Similar to 'm', but don't use define_memory_constraint on x86-64 ;; to prevent LRA from converting the operand to the form '(mem (reg X))' ;; where X is a base register. (define_constraint "BM" "@internal x86-64 memory operand." (and (match_code "mem") (match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0), MEM_ADDR_SPACE (op))"))) ;; Memory operand constraint for word modes. (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
On Mon, Dec 20, 2021 at 11:44:08AM -0800, H.J. Lu wrote: > The problem is in > > (define_memory_constraint "TARGET_MEM_CONSTRAINT" > "Matches any valid memory." > (and (match_code "mem") > (match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0), > MEM_ADDR_SPACE (op))"))) > > define_register_constraint allows LRA to convert the operand to the form > '(mem (reg X))', where X is a base register. I am testing the v2 patch with If you mean replacing an immediate with a MEM containing that immediate, isn't that often the right thing though? I mean, if the register pressure is high and options are either spill some register, set it to immediate, use it in one instruction and then fill the spilled register (i.e. 2 memory loads), compared to a MEM use on the arithmetic instruction one MEM seems cheaper to me. With -fPIC and the cst needing runtime relocation slightly less so of course. The code due to ivopts is trying to have something like size_t a = (size_t) &tunable_list; size_t b = 0xffffffffffffffa8 - a; size_t c = x + b; and for that cst - &symbol one needs actually 2 registers, one to hold the constant and one to hold the (%rip) based address. (insn 790 789 791 111 (set (reg:DI 292) (const_int -88 [0xffffffffffffffa8])) "dl-tunables.c":304:15 76 {*movdi_internal} (nil)) (insn 791 790 792 111 (set (reg:DI 293) (symbol_ref:DI ("tunable_list") [flags 0x2] <var_decl 0x7f3460aa9cf0 tunable_list>)) "dl-tunables.c":304:15 76 {*movdi_internal} (nil)) (insn 792 791 793 111 (parallel [ (set (reg:DI 291) (minus:DI (reg:DI 292) (reg:DI 293))) (clobber (reg:CC 17 flags)) ]) "dl-tunables.c":304:15 299 {*subdi_1} (nil)) (insn 793 792 794 111 (parallel [ (set (reg:DI 294) (plus:DI (reg:DI 291) (reg:DI 198 [ ivtmp.176 ]))) (clobber (reg:CC 17 flags)) ]) "dl-tunables.c":304:15 226 {*adddi_1} (nil)) It would be smarter to rewrite the above into a lea 88+tunable_list(%rip), %temp1 and use a subtraction instead of addition in the last insn above, or of course in the particular case even consider the following 2 instructions that do: (insn 794 793 795 111 (set (reg:DI 296) (symbol_ref:DI ("tunable_list") [flags 0x2] <var_decl 0x7f3460aa9cf0 tunable_list>)) "dl-tunables.c":304:15 76 {*movdi_internal} (nil)) (insn 795 794 796 111 (parallel [ (set (reg:DI 295 [ cur ]) (plus:DI (reg:DI 294) (reg:DI 296))) (clobber (reg:CC 17 flags)) ]) "dl-tunables.c":304:15 226 {*adddi_1} (nil)) and find out that &tuneble_list - &tuneble_list is 0 and we don't need it at all. Guess we don't figure that out due to the cast of one of those addresses to size_t and the other one used in POINTER_PLUS_EXPR as normal pointer. Jakub
diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 6b291a02d88..6677285e518 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -168,6 +168,7 @@ ;; z Constant call address operand. ;; C Integer SSE constant with all bits set operand. ;; F Floating-point SSE constant with all bits set operand. +;; M ix86 memory operand. (define_constraint "Bf" "@internal Flags register operand." @@ -232,6 +233,10 @@ (and (match_test "TARGET_SSE") (match_operand 0 "float_vector_all_ones_operand"))) +(define_constraint "BM" + "@internal ix86 memory operand." + (match_operand 0 "ix86_memory_operand")) + ;; Integer constant constraints. (define_constraint "Wb" "Integer constant in the range 0 @dots{} 7, for 8-bit shifts." diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index d25453fe574..4f30819a1d9 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1385,7 +1385,7 @@ (define_insn "*cmp<mode>_1" [(set (reg FLAGS_REG) (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") - (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))] + (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>BM")))] "ix86_match_ccmode (insn, CCmode)" "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" [(set_attr "type" "icmp") @@ -1395,7 +1395,7 @@ [(set (reg FLAGS_REG) (compare (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") - (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")) + (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>BM")) (const_int 0)))] "ix86_match_ccmode (insn, CCGOCmode)" "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" @@ -5653,7 +5653,7 @@ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r") (plus:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r") - (match_operand:SWI48 2 "x86_64_general_operand" "re,m,0,le"))) + (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" { @@ -5709,7 +5709,7 @@ [(set (match_operand:DI 0 "register_operand" "=r,r,r") (zero_extend:DI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r") - (match_operand:SI 2 "x86_64_general_operand" "rme,0,le")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" { @@ -5967,7 +5967,7 @@ (compare (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>") - (match_operand:SWI 2 "<general_operand>" "<r><i>,m,0")) + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM,0")) (const_int 0))) (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>") (plus:SWI (match_dup 1) (match_dup 2)))] @@ -6012,7 +6012,7 @@ [(set (reg FLAGS_REG) (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") - (match_operand:SI 2 "x86_64_general_operand" "rme,0")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe,0")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r,r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -6097,7 +6097,7 @@ (define_insn "*addsi_3_zext" [(set (reg FLAGS_REG) (compare - (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0")) + (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0")) (match_operand:SI 1 "nonimmediate_operand" "%0,r"))) (set (match_operand:DI 0 "register_operand" "=r,r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -6801,7 +6801,7 @@ [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") (minus:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,0") - (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" "sub{<imodesuffix>}\t{%2, %0|%0, %2}" @@ -6812,7 +6812,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "x86_64_general_operand" "rme")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" "sub{l}\t{%2, %k0|%k0, %2}" @@ -6844,7 +6844,7 @@ (compare (minus:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,0") - (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM")) (const_int 0))) (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") (minus:SWI (match_dup 1) (match_dup 2)))] @@ -6858,7 +6858,7 @@ [(set (reg FLAGS_REG) (compare (minus:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "x86_64_general_operand" "rme")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI @@ -7111,7 +7111,7 @@ (define_insn "*sub<mode>_3" [(set (reg FLAGS_REG) (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0") - (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM"))) (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") (minus:SWI (match_dup 1) (match_dup 2)))] "ix86_match_ccmode (insn, CCmode) @@ -7187,7 +7187,7 @@ (define_insn "*subsi_3_zext" [(set (reg FLAGS_REG) (compare (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "x86_64_general_operand" "rme"))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe"))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (minus:SI (match_dup 1) @@ -7207,7 +7207,7 @@ (match_operator:SWI 4 "ix86_carry_flag_operator" [(match_operand 3 "flags_reg_operand") (const_int 0)]) (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) - (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" "adc{<imodesuffix>}\t{%2, %0|%0, %2}" @@ -7251,7 +7251,7 @@ (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator" [(reg FLAGS_REG) (const_int 0)]) (match_operand:SI 1 "register_operand" "%0")) - (match_operand:SI 2 "x86_64_general_operand" "rme")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" "adc{l}\t{%2, %k0|%k0, %2}" @@ -7377,7 +7377,7 @@ (match_operand:SWI 1 "nonimmediate_operand" "0,0") (match_operator:SWI 4 "ix86_carry_flag_operator" [(match_operand 3 "flags_reg_operand") (const_int 0)])) - (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" @@ -7422,7 +7422,7 @@ (match_operand:SI 1 "register_operand" "0") (match_operator:SI 3 "ix86_carry_flag_operator" [(reg FLAGS_REG) (const_int 0)])) - (match_operand:SI 2 "x86_64_general_operand" "rme")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" "sbb{l}\t{%2, %k0|%k0, %2}" @@ -7498,7 +7498,7 @@ (define_insn "@sub<mode>3_carry_ccgz" [(set (reg:CCGZ FLAGS_REG) (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0") - (match_operand:DWIH 2 "x86_64_general_operand" "rme") + (match_operand:DWIH 2 "x86_64_general_operand" "rBMe") (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))] UNSPEC_SBB)) (clobber (match_scratch:DWIH 0 "=r"))] @@ -7585,7 +7585,7 @@ (compare:CCC (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM")) (match_dup 1))) (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") (plus:SWI (match_dup 1) (match_dup 2)))] @@ -7616,7 +7616,7 @@ (compare:CCC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) (match_dup 1))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -7643,7 +7643,7 @@ (compare:CCC (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM")) (match_dup 2))) (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") (plus:SWI (match_dup 1) (match_dup 2)))] @@ -7657,7 +7657,7 @@ (compare:CCC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) (match_dup 2))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -8001,7 +8001,7 @@ [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r") (mult:SWIM248 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0") - (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr"))) + (match_operand:SWIM248 2 "<general_operand>" "K,<i>,BMr"))) (clobber (reg:CC FLAGS_REG))] "!(MEM_P (operands[1]) && MEM_P (operands[2]))" "@ @@ -8037,7 +8037,7 @@ [(set (match_operand:DI 0 "register_operand" "=r,r,r") (zero_extend:DI (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") - (match_operand:SI 2 "x86_64_general_operand" "K,e,mr")))) + (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && !(MEM_P (operands[1]) && MEM_P (operands[2]))" @@ -9711,7 +9711,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" "and{l}\t{%2, %k0|%k0, %2}" @@ -9721,7 +9721,7 @@ (define_insn "*and<mode>_1" [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k") (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k") - (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L,k"))) + (match_operand:SWI24 2 "<general_operand>" "r<i>,BM,L,k"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, <MODE>mode, operands)" "@ @@ -9903,7 +9903,7 @@ [(set (reg FLAGS_REG) (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] @@ -9946,7 +9946,7 @@ [(set (reg FLAGS_REG) (compare (and:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI124 2 "<general_operand>" "<r><i>,m")) + (match_operand:SWI124 2 "<general_operand>" "<r><i>,BM")) (const_int 0))) (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>") (and:SWI124 (match_dup 1) (match_dup 2)))] @@ -10260,7 +10260,7 @@ [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k") (any_or:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k") - (match_operand:SWI248 2 "<general_operand>" "r<i>,m,k"))) + (match_operand:SWI248 2 "<general_operand>" "r<i>,BM,k"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" "@ @@ -10328,7 +10328,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")))) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" "<logic>{l}\t{%2, %k0|%k0, %2}" @@ -10431,7 +10431,7 @@ [(set (reg FLAGS_REG) (compare (any_or:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) + (match_operand:SWI 2 "<general_operand>" "<r><i>,BM")) (const_int 0))) (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") (any_or:SWI (match_dup 1) (match_dup 2)))] @@ -10446,7 +10446,7 @@ (define_insn "*<code>si_2_zext" [(set (reg FLAGS_REG) (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "x86_64_general_operand" "rme")) + (match_operand:SI 2 "x86_64_general_operand" "rBMe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 770e2f0c0dd..cfc0a50e239 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1199,6 +1199,12 @@ (and (match_operand 0 "memory_operand") (not (match_test "x86_extended_reg_mentioned_p (op)")))) +;; Return true if OP is a memory operand representable on ix86. +(define_predicate "ix86_memory_operand" + (and (match_operand 0 "memory_operand") + (ior (match_test "mode == QImode || mode == HImode") + (match_operand 0 "x86_64_general_operand")))) + ;; Return true for RTX codes that force SImode address. (define_predicate "SImode_address_operand" (match_code "subreg,zero_extend,and")) diff --git a/gcc/testsuite/gcc.target/i386/pr103762-1a.c b/gcc/testsuite/gcc.target/i386/pr103762-1a.c new file mode 100644 index 00000000000..c9e75bc12d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103762-1a.c @@ -0,0 +1,647 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -std=gnu11 -fgnu89-inline" } */ +/* { dg-final { scan-assembler-not ".quad\[\\t \]+tunable_list" { target lp64 } } } */ +/* { dg-final { scan-assembler-not ".long\[\\t \]+tunable_list" { target { ! lp64 } } } } */ + +typedef unsigned long int size_t; +typedef long long int intmax_t; +typedef unsigned long long int uintmax_t; +typedef unsigned long long int uint64_t; +typedef intmax_t tunable_num_t; +typedef union +{ + tunable_num_t numval; + const char *strval; +} tunable_val_t; +enum +{ + HWCAP_X86_SSE2 = 1 << 0, + HWCAP_X86_64 = 1 << 1, + HWCAP_X86_AVX512_1 = 1 << 2 +}; +typedef void (*tunable_callback_t) (tunable_val_t *); +extern void *__minimal_malloc (size_t n) + __attribute__ ((visibility ("hidden"))); +extern int __libc_enable_secure __attribute__ ((section (".data.rel.ro"))); +extern uint64_t _dl_strtoul (const char *, char **) + __attribute__ ((visibility ("hidden"))); +extern void _dl_fatal_printf (const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 1, 2), __noreturn__)); +typedef enum +{ + glibc_rtld_nns, + glibc_elision_skip_lock_after_retries, + glibc_malloc_trim_threshold, + glibc_malloc_perturb, + glibc_cpu_x86_shared_cache_size, + glibc_pthread_rseq, + glibc_mem_tagging, + glibc_elision_tries, + glibc_elision_enable, + glibc_malloc_hugetlb, + glibc_cpu_x86_rep_movsb_threshold, + glibc_malloc_mxfast, + glibc_rtld_dynamic_sort, + glibc_elision_skip_lock_busy, + glibc_malloc_top_pad, + glibc_cpu_x86_rep_stosb_threshold, + glibc_cpu_x86_non_temporal_threshold, + glibc_cpu_x86_shstk, + glibc_pthread_stack_cache_size, + glibc_cpu_hwcap_mask, + glibc_malloc_mmap_max, + glibc_elision_skip_trylock_internal_abort, + glibc_malloc_tcache_unsorted_limit, + glibc_cpu_x86_ibt, + glibc_cpu_hwcaps, + glibc_elision_skip_lock_internal_abort, + glibc_malloc_arena_max, + glibc_malloc_mmap_threshold, + glibc_cpu_x86_data_cache_size, + glibc_malloc_tcache_count, + glibc_malloc_arena_test, + glibc_pthread_mutex_spin_count, + glibc_rtld_optional_static_tls, + glibc_malloc_tcache_max, + glibc_malloc_check, +} tunable_id_t; +typedef enum +{ + TUNABLE_TYPE_INT_32, + TUNABLE_TYPE_UINT_64, + TUNABLE_TYPE_SIZE_T, + TUNABLE_TYPE_STRING +} tunable_type_code_t; +typedef struct +{ + tunable_type_code_t type_code; + tunable_num_t min; + tunable_num_t max; +} tunable_type_t; +typedef enum +{ + TUNABLE_SECLEVEL_SXID_ERASE = 0, + TUNABLE_SECLEVEL_SXID_IGNORE = 1, + TUNABLE_SECLEVEL_NONE = 2, +} tunable_seclevel_t; +struct _tunable +{ + const char name[42]; + tunable_type_t type; + tunable_val_t val; + _Bool initialized; + tunable_seclevel_t security_level; + const char env_alias[23]; +}; +typedef struct _tunable tunable_t; +extern _Bool unsigned_tunable_type (tunable_type_code_t t); + +static tunable_t tunable_list[] __attribute__ ((section (".data.rel.ro"))) = { + { "glibc" + "." + "rtld" + "." + "nns", + { TUNABLE_TYPE_SIZE_T, 1, 16 }, + { .numval = 4 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "elision" + "." + "skip_lock_after_retries", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + { .numval = 3 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "trim_threshold", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_TRIM_THRESHOLD_" }, + { "glibc" + "." + "malloc" + "." + "perturb", + { TUNABLE_TYPE_INT_32, 0, 0xff }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_PERTURB_" }, + { "glibc" + "." + "cpu" + "." + "x86_shared_cache_size", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "pthread" + "." + "rseq", + { TUNABLE_TYPE_INT_32, 0, 1 }, + { .numval = 1 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "mem" + "." + "tagging", + { TUNABLE_TYPE_INT_32, 0, 255 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + { 0 } }, + { "glibc" + "." + "elision" + "." + "tries", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + { .numval = 3 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "elision" + "." + "enable", + { TUNABLE_TYPE_INT_32, 0, 1 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "hugetlb", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "x86_rep_movsb_threshold", + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "mxfast", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + { 0 } }, + { "glibc" + "." + "rtld" + "." + "dynamic_sort", + { TUNABLE_TYPE_INT_32, 1, 2 }, + { .numval = 2 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "elision" + "." + "skip_lock_busy", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + { .numval = 3 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "top_pad", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_TOP_PAD_" }, + { "glibc" + "." + "cpu" + "." + "x86_rep_stosb_threshold", + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, + { .numval = 2048 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "x86_non_temporal_threshold", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "x86_shstk", + { TUNABLE_TYPE_STRING, 0, 0 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "pthread" + "." + "stack_cache_size", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + { .numval = 41943040 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "hwcap_mask", + { TUNABLE_TYPE_UINT_64, 0, (18446744073709551615UL) }, + { .numval = (HWCAP_X86_64 | HWCAP_X86_AVX512_1) }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + "LD_HWCAP_MASK" }, + { "glibc" + "." + "malloc" + "." + "mmap_max", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_MMAP_MAX_" }, + { "glibc" + "." + "elision" + "." + "skip_trylock_internal_abort", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + { .numval = 3 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "tcache_unsorted_limit", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "x86_ibt", + { TUNABLE_TYPE_STRING, 0, 0 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "cpu" + "." + "hwcaps", + { TUNABLE_TYPE_STRING, 0, 0 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "elision" + "." + "skip_lock_internal_abort", + { TUNABLE_TYPE_INT_32, 0, (2147483647) }, + { .numval = 3 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "arena_max", + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_ARENA_MAX" }, + { "glibc" + "." + "malloc" + "." + "mmap_threshold", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_MMAP_THRESHOLD_" }, + { "glibc" + "." + "cpu" + "." + "x86_data_cache_size", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "tcache_count", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "arena_test", + { TUNABLE_TYPE_SIZE_T, 1, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_IGNORE, + "MALLOC_ARENA_TEST" }, + { "glibc" + "." + "pthread" + "." + "mutex_spin_count", + { TUNABLE_TYPE_INT_32, 0, 32767 }, + { .numval = 100 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "rtld" + "." + "optional_static_tls", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + { .numval = 512 }, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "tcache_max", + { TUNABLE_TYPE_SIZE_T, 0, (18446744073709551615UL) }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + { 0 } }, + { "glibc" + "." + "malloc" + "." + "check", + { TUNABLE_TYPE_INT_32, 0, 3 }, + {}, + ((void *)0), + TUNABLE_SECLEVEL_SXID_ERASE, + "MALLOC_CHECK_" }, +}; +extern void __tunables_init (char **); +extern void __tunables_print (void); +extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t); +extern void __tunable_set_val (tunable_id_t, tunable_val_t *, tunable_num_t *, + tunable_num_t *); +static __inline __attribute__ ((__always_inline__)) _Bool +tunable_val_lt (tunable_num_t lhs, tunable_num_t rhs, _Bool unsigned_cmp) +{ + if (unsigned_cmp) + return (uintmax_t)lhs < (uintmax_t)rhs; + else + return lhs < rhs; +} +static __inline __attribute__ ((__always_inline__)) _Bool +tunable_val_gt (tunable_num_t lhs, tunable_num_t rhs, _Bool unsigned_cmp) +{ + if (unsigned_cmp) + return (uintmax_t)lhs > (uintmax_t)rhs; + else + return lhs > rhs; +} +static __inline __attribute__ ((__always_inline__)) _Bool +tunable_is_name (const char *orig, const char *envname) +{ + for (; *orig != '\0' && *envname != '\0'; envname++, orig++) + if (*orig != *envname) + break; + if (*orig == '\0' && *envname == '=') + return 1; + else + return 0; +} +static char * +tunables_strdup (const char *in) +{ + size_t i = 0; + while (in[i++] != '\0') + ; + char *out = __minimal_malloc (i + 1); + if (out == ((void *)0)) + _dl_fatal_printf ("failed to allocate memory to process tunables\n"); + while (i-- > 0) + out[i] = in[i]; + return out; +} +static char ** +get_next_env (char **envp, char **name, size_t *namelen, char **val, + char ***prev_envp) +{ + while (envp != ((void *)0) && *envp != ((void *)0)) + { + char **prev = envp; + char *envline = *envp++; + int len = 0; + while (envline[len] != '\0' && envline[len] != '=') + len++; + if (envline[len] == '\0') + continue; + *name = envline; + *namelen = len; + *val = &envline[len + 1]; + *prev_envp = prev; + return envp; + } + return ((void *)0); +} +static void +do_tunable_update_val (tunable_t *cur, const tunable_val_t *valp, + const tunable_num_t *minp, const tunable_num_t *maxp) +{ + tunable_num_t val, min, max; + if (cur->type.type_code == TUNABLE_TYPE_STRING) + { + cur->val.strval = valp->strval; + cur->initialized = 1; + return; + } + _Bool unsigned_cmp = unsigned_tunable_type (cur->type.type_code); + val = valp->numval; + min = minp != ((void *)0) ? *minp : cur->type.min; + max = maxp != ((void *)0) ? *maxp : cur->type.max; + if (tunable_val_lt (min, cur->type.min, unsigned_cmp)) + min = cur->type.min; + if (tunable_val_gt (max, cur->type.max, unsigned_cmp)) + max = cur->type.max; + if (tunable_val_gt (min, max, unsigned_cmp)) + { + min = cur->type.min; + max = cur->type.max; + } + if (tunable_val_lt (val, min, unsigned_cmp) + || tunable_val_lt (max, val, unsigned_cmp)) + return; + cur->val.numval = val; + cur->type.min = min; + cur->type.max = max; + cur->initialized = 1; +} +static void +tunable_initialize (tunable_t *cur, const char *strval) +{ + tunable_val_t val; + if (cur->type.type_code != TUNABLE_TYPE_STRING) + val.numval = (tunable_num_t)_dl_strtoul (strval, ((void *)0)); + else + val.strval = strval; + do_tunable_update_val (cur, &val, ((void *)0), ((void *)0)); +} +static void +parse_tunables (char *tunestr, char *valstring) +{ + if (tunestr == ((void *)0) || *tunestr == '\0') + return; + char *p = tunestr; + size_t off = 0; + while (1) + { + char *name = p; + size_t len = 0; + while (p[len] != '=' && p[len] != ':' && p[len] != '\0') + len++; + if (p[len] == '\0') + { + if (__libc_enable_secure) + tunestr[off] = '\0'; + return; + } + if (p[len] == ':') + { + p += len + 1; + continue; + } + p += len + 1; + char *value = &valstring[p - tunestr]; + len = 0; + while (p[len] != ':' && p[len] != '\0') + len++; + for (size_t i = 0; i < sizeof (tunable_list) / sizeof (tunable_t); i++) + { + tunable_t *cur = &tunable_list[i]; + if (tunable_is_name (cur->name, name)) + { + if (__libc_enable_secure) + { + if (cur->security_level != TUNABLE_SECLEVEL_SXID_ERASE) + { + if (off > 0) + tunestr[off++] = ':'; + const char *n = cur->name; + while (*n != '\0') + tunestr[off++] = *n++; + tunestr[off++] = '='; + for (size_t j = 0; j < len; j++) + tunestr[off++] = value[j]; + } + if (cur->security_level != TUNABLE_SECLEVEL_NONE) + break; + } + value[len] = '\0'; + tunable_initialize (cur, value); + break; + } + } + if (p[len] != '\0') + p += len + 1; + } +} +void +__tunables_init (char **envp) +{ + char *envname = ((void *)0); + char *envval = ((void *)0); + size_t len = 0; + char **prev_envp = envp; + while ((envp = get_next_env (envp, &envname, &len, &envval, &prev_envp)) + != ((void *)0)) + { + if (tunable_is_name ("GLIBC_TUNABLES", envname)) + { + char *new_env = tunables_strdup (envname); + if (new_env != ((void *)0)) + parse_tunables (new_env + len + 1, envval); + *prev_envp = new_env; + continue; + } + for (int i = 0; i < sizeof (tunable_list) / sizeof (tunable_t); i++) + { + tunable_t *cur = &tunable_list[i]; + const char *name = cur->env_alias; + if (tunable_is_name (name, envname)) + { + tunable_initialize (cur, envval); + break; + } + } + } +} diff --git a/gcc/testsuite/gcc.target/i386/pr103762-1b.c b/gcc/testsuite/gcc.target/i386/pr103762-1b.c new file mode 100644 index 00000000000..391f51cf7f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103762-1b.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target pie } */ +/* { dg-options "-O2 -std=gnu11 -fgnu89-inline -fpie" } */ +/* { dg-final { scan-assembler-not ".quad\[\\t \]+tunable_list" { target lp64 } } } */ +/* { dg-final { scan-assembler-not ".long\[\\t \]+tunable_list" { target { ! lp64 } } } } */ + +#include "pr103762-1a.c" diff --git a/gcc/testsuite/gcc.target/i386/pr103762-1c.c b/gcc/testsuite/gcc.target/i386/pr103762-1c.c new file mode 100644 index 00000000000..4667b06c171 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103762-1c.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fpic } */ +/* { dg-options "-O2 -std=gnu11 -fgnu89-inline -fpic" } */ +/* { dg-final { scan-assembler-not ".quad\[\\t \]+tunable_list" { target lp64 } } } */ +/* { dg-final { scan-assembler-not ".long\[\\t \]+tunable_list" { target { ! lp64 } } } } */ + +#include "pr103762-1a.c"