Skip to content

[clang] Generate nuw GEPs for struct member accesses #99538

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 9, 2024

Conversation

hazzlim
Copy link
Contributor

@hazzlim hazzlim commented Jul 18, 2024

Generate nuw GEPs for struct member accesses, as these are always constant positive offsets derived from the index of the struct member.

Regression tests are updated using update_cc_test_checks.py where possible, and by find + replace where not.

@hazzlim hazzlim requested review from SLTozer, nikic and s-barannikov and removed request for SLTozer and nikic July 18, 2024 18:09
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:AMDGPU backend:RISC-V backend:PowerPC backend:SystemZ backend:X86 clang:codegen IR generation bugs: mangling, exceptions, etc. HLSL HLSL Language Support coroutines C++20 coroutines llvm:ir clang:openmp OpenMP related changes to Clang labels Jul 18, 2024
@hazzlim hazzlim requested a review from david-arm July 18, 2024 18:10
@llvmbot
Copy link
Member

llvmbot commented Jul 18, 2024

@llvm/pr-subscribers-mlir-llvm
@llvm/pr-subscribers-mlir
@llvm/pr-subscribers-flang-openmp
@llvm/pr-subscribers-backend-webassembly
@llvm/pr-subscribers-backend-nvptx
@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-llvm-ir
@llvm/pr-subscribers-backend-x86
@llvm/pr-subscribers-hlsl
@llvm/pr-subscribers-backend-powerpc
@llvm/pr-subscribers-backend-amdgpu
@llvm/pr-subscribers-coroutines

@llvm/pr-subscribers-clang

Author: Hari Limaye (hazzlim)

Changes

Generate nuw GEPs for struct member accesses, as these are always constant positive offsets derived from the index of the struct member.

Regression tests are updated using update_cc_test_checks.py where possible, and by find + replace where not.


Patch is 7.54 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/99538.diff

456 Files Affected:

  • (modified) clang/lib/CodeGen/CGBuilder.h (+3-3)
  • (modified) clang/test/C/C2y/n3254.c (+13-13)
  • (modified) clang/test/C/C2y/n3259.c (+16-16)
  • (modified) clang/test/CodeGen/PowerPC/powerpc-c99complex.c (+6-6)
  • (modified) clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c (+1-1)
  • (modified) clang/test/CodeGen/RISCV/bfloat-abi.c (+60-60)
  • (modified) clang/test/CodeGen/RISCV/riscv32-vararg.c (+42-42)
  • (modified) clang/test/CodeGen/RISCV/riscv64-vararg.c (+27-27)
  • (modified) clang/test/CodeGen/SystemZ/systemz-abi-vector.c (+52-52)
  • (modified) clang/test/CodeGen/SystemZ/systemz-abi.c (+61-61)
  • (modified) clang/test/CodeGen/X86/Float16-arithmetic.c (+25-25)
  • (modified) clang/test/CodeGen/X86/Float16-complex.c (+328-328)
  • (modified) clang/test/CodeGen/X86/cx-complex-range.c (+197-192)
  • (modified) clang/test/CodeGen/X86/va-arg-sse.c (+25-25)
  • (modified) clang/test/CodeGen/X86/x86_64-floatvectors.c (+14-14)
  • (modified) clang/test/CodeGen/X86/x86_64-vaarg.c (+5-5)
  • (modified) clang/test/CodeGen/aapcs-bitfield.c (+216-216)
  • (modified) clang/test/CodeGen/aarch64-neon-intrinsics.c (+360-360)
  • (modified) clang/test/CodeGen/aarch64-neon-ldst-one.c (+672-672)
  • (modified) clang/test/CodeGen/aarch64-neon-perm.c (+54-54)
  • (modified) clang/test/CodeGen/aarch64-neon-tbl.c (+156-156)
  • (modified) clang/test/CodeGen/aarch64-poly64.c (+24-24)
  • (modified) clang/test/CodeGen/aarch64-soft-float-abi.c (+4-4)
  • (modified) clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-generic.c (+6-6)
  • (modified) clang/test/CodeGen/address-space-field1.c (+4-4)
  • (modified) clang/test/CodeGen/align_value.cpp (+2-2)
  • (modified) clang/test/CodeGen/alloc-align-attr.c (+31-31)
  • (modified) clang/test/CodeGen/annotations-field.c (+1-1)
  • (modified) clang/test/CodeGen/arm-neon-vst.c (+288-288)
  • (modified) clang/test/CodeGen/arm-swiftcall.c (+78-78)
  • (modified) clang/test/CodeGen/arm-varargs.c (+2-2)
  • (modified) clang/test/CodeGen/arm64-arguments.c (+48-48)
  • (modified) clang/test/CodeGen/arm64-be-bitfield.c (+1-1)
  • (modified) clang/test/CodeGen/arm64-be-hfa-vararg.c (+2-2)
  • (modified) clang/test/CodeGen/arm_neon_intrinsics.c (+708-708)
  • (modified) clang/test/CodeGen/attr-arm-sve-vector-bits-bitcast.c (+24-24)
  • (modified) clang/test/CodeGen/attr-counted-by-pr88931.c (+1-1)
  • (modified) clang/test/CodeGen/attr-counted-by.c (+50-50)
  • (modified) clang/test/CodeGen/block-byref-aggr.c (+8-8)
  • (modified) clang/test/CodeGen/blocks-seq.c (+2-2)
  • (modified) clang/test/CodeGen/blocks.c (+4-4)
  • (modified) clang/test/CodeGen/builtin-complex.c (+2-2)
  • (modified) clang/test/CodeGen/builtin-dump-struct.c (+31-31)
  • (modified) clang/test/CodeGen/builtins.c (+4-4)
  • (modified) clang/test/CodeGen/c11atomics-ios.c (+30-30)
  • (modified) clang/test/CodeGen/c11atomics.c (+32-32)
  • (modified) clang/test/CodeGen/capture-complex-expr-in-block.c (+2-2)
  • (modified) clang/test/CodeGen/captured-statements-nested.c (+20-20)
  • (modified) clang/test/CodeGen/captured-statements.c (+2-2)
  • (modified) clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-lvalue.cpp (+1-1)
  • (modified) clang/test/CodeGen/complex-convert.c (+176-176)
  • (modified) clang/test/CodeGen/compound-literal.c (+7-7)
  • (modified) clang/test/CodeGen/cx-complex-range.c (+764-764)
  • (modified) clang/test/CodeGen/ext-int.c (+9-9)
  • (modified) clang/test/CodeGen/matrix-type-builtins.c (+2-2)
  • (modified) clang/test/CodeGen/matrix-type.c (+2-2)
  • (modified) clang/test/CodeGen/ms-anonymous-struct.c (+24-24)
  • (modified) clang/test/CodeGen/packed-structure.c (+1-1)
  • (modified) clang/test/CodeGen/paren-list-agg-init.cpp (+41-41)
  • (modified) clang/test/CodeGen/pragma-cx-limited-range.c (+2-2)
  • (modified) clang/test/CodeGen/smiths-complex-div.c (+6-6)
  • (modified) clang/test/CodeGen/transparent-union-redecl.c (+3-3)
  • (modified) clang/test/CodeGen/unaligned-expr.c (+2-2)
  • (modified) clang/test/CodeGen/variadic-gpfp-x86.c (+1-1)
  • (modified) clang/test/CodeGen/variadic-nvptx.c (+9-9)
  • (modified) clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp (+3-3)
  • (modified) clang/test/CodeGen/windows-swiftcall.c (+56-56)
  • (modified) clang/test/CodeGenCUDA/lambda-reference-var.cu (+3-3)
  • (modified) clang/test/CodeGenCUDA/record-layout.cu (+6-6)
  • (modified) clang/test/CodeGenCXX/RelativeVTablesABI/type-info.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/alignment.cpp (+8-8)
  • (modified) clang/test/CodeGenCXX/arm-swiftcall.cpp (+16-16)
  • (modified) clang/test/CodeGenCXX/asm.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/attr-annotate.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp (+9-9)
  • (modified) clang/test/CodeGenCXX/auto-var-init.cpp (+24-24)
  • (modified) clang/test/CodeGenCXX/bitfield-ir.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/bitfield.cpp (+16-16)
  • (modified) clang/test/CodeGenCXX/block-capture.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/block-inalloca.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/blocks-cxx11.cpp (+4-4)
  • (modified) clang/test/CodeGenCXX/blocks.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/builtin-dump-struct.cpp (+8-8)
  • (modified) clang/test/CodeGenCXX/captured-statements.cpp (+6-6)
  • (modified) clang/test/CodeGenCXX/catch-undef-behavior.cpp (+4-4)
  • (modified) clang/test/CodeGenCXX/copy-constructor-synthesis.cpp (+4-4)
  • (modified) clang/test/CodeGenCXX/cxx11-initializer-aggregate.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp (+6-6)
  • (modified) clang/test/CodeGenCXX/cxx1z-lambda-star-this.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/cxx20-consteval-crash.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/cxx20-decomposition.cpp (+6-6)
  • (modified) clang/test/CodeGenCXX/cxx2a-compare.cpp (+5-5)
  • (modified) clang/test/CodeGenCXX/cxx2a-consteval.cpp (+10-10)
  • (modified) clang/test/CodeGenCXX/cxx2b-deducing-this.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/debug-info-lambda.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp (+7-7)
  • (modified) clang/test/CodeGenCXX/decl-ref-inheritance.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/eh-aggregated-inits-unwind.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/exceptions.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/ext-int.cpp (+9-9)
  • (modified) clang/test/CodeGenCXX/ibm128-declarations.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/inalloca-lambda.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/inalloca-overaligned.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/inalloca-vector.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/lambda-deterministic-captures.cpp (+6-6)
  • (modified) clang/test/CodeGenCXX/matrix-type-builtins.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/matrix-type-operators.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/matrix-type.cpp (+9-9)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp (+6-6)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-explicit-object-parameters.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp (+5-5)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/new-array-init.cpp (+8-8)
  • (modified) clang/test/CodeGenCXX/noescape.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/nrvo.cpp (+158-158)
  • (modified) clang/test/CodeGenCXX/partial-destruction.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/pr20897.cpp (+4-4)
  • (modified) clang/test/CodeGenCXX/strict-vtable-pointers.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/temporaries.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/trivial-auto-var-init.cpp (+4-4)
  • (modified) clang/test/CodeGenCXX/trivial_abi.cpp (+9-9)
  • (modified) clang/test/CodeGenCXX/trivial_abi_debuginfo.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/ubsan-global-alignment.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/virtual-bases.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/vla-lambda-capturing.cpp (+30-30)
  • (modified) clang/test/CodeGenCXX/x86_64-vaarg.cpp (+3-3)
  • (modified) clang/test/CodeGenCoroutines/coro-await.cpp (+1-1)
  • (modified) clang/test/CodeGenCoroutines/coro-params.cpp (+2-2)
  • (modified) clang/test/CodeGenHLSL/buffer-array-operator.hlsl (+2-2)
  • (modified) clang/test/CodeGenHLSL/this-assignment-overload.hlsl (+4-4)
  • (modified) clang/test/CodeGenHLSL/this-assignment.hlsl (+2-2)
  • (modified) clang/test/CodeGenHLSL/this-reference.hlsl (+2-2)
  • (modified) clang/test/CodeGenObjC/arc-blocks.m (+45-45)
  • (modified) clang/test/CodeGenObjC/arc-foreach.m (+8-8)
  • (modified) clang/test/CodeGenObjC/arc-unoptimized-byref-var.m (+2-2)
  • (modified) clang/test/CodeGenObjC/asm.m (+2-2)
  • (modified) clang/test/CodeGenObjC/block-6.m (+3-3)
  • (modified) clang/test/CodeGenObjC/blocks-2.m (+1-1)
  • (modified) clang/test/CodeGenObjC/blocks.m (+12-12)
  • (modified) clang/test/CodeGenObjC/category-super-class-meth.m (+1-1)
  • (modified) clang/test/CodeGenObjC/class-stubs.m (+2-2)
  • (modified) clang/test/CodeGenObjC/noescape.m (+6-6)
  • (modified) clang/test/CodeGenObjC/nontrivial-c-struct-property.m (+2-2)
  • (modified) clang/test/CodeGenObjC/nontrivial-struct-param-init.m (+1-1)
  • (modified) clang/test/CodeGenObjC/ns_consume_null_check.m (+4-4)
  • (modified) clang/test/CodeGenObjC/objc-dispatch-null-check.m (+2-2)
  • (modified) clang/test/CodeGenObjC/objc-non-trivial-struct-nrvo.m (+1-1)
  • (modified) clang/test/CodeGenObjC/property-array-type.m (+1-1)
  • (modified) clang/test/CodeGenObjC/strong-in-c-struct.m (+18-18)
  • (modified) clang/test/CodeGenObjCXX/arc-blocks.mm (+24-24)
  • (modified) clang/test/CodeGenObjCXX/arc-cxx11-init-list.mm (+1-1)
  • (modified) clang/test/CodeGenObjCXX/arc-cxx11-member-init.mm (+1-1)
  • (modified) clang/test/CodeGenObjCXX/arc-exceptions.mm (+2-2)
  • (modified) clang/test/CodeGenObjCXX/arc-indirect.mm (+1-1)
  • (modified) clang/test/CodeGenObjCXX/arc-special-member-functions.mm (+2-2)
  • (modified) clang/test/CodeGenObjCXX/block-default-arg.mm (+1-1)
  • (modified) clang/test/CodeGenObjCXX/block-nested-in-lambda.mm (+16-16)
  • (modified) clang/test/CodeGenObjCXX/gc.mm (+1-1)
  • (modified) clang/test/CodeGenObjCXX/lambda-expressions.mm (+5-5)
  • (modified) clang/test/CodeGenObjCXX/lambda-to-block.mm (+4-4)
  • (modified) clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm (+6-6)
  • (modified) clang/test/CodeGenObjCXX/property-object-conditional-exp.mm (+2-2)
  • (modified) clang/test/CodeGenObjCXX/property-objects.mm (+1-1)
  • (modified) clang/test/CodeGenOpenCL/addr-space-struct-arg.cl (+1-1)
  • (modified) clang/test/CodeGenOpenCL/amdgpu-abi-struct-arg-byref.cl (+24-24)
  • (modified) clang/test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl (+152-151)
  • (modified) clang/test/CodeGenOpenCL/blocks.cl (+10-10)
  • (modified) clang/test/CodeGenOpenCL/cl20-device-side-enqueue-attributes.cl (+30-30)
  • (modified) clang/test/CodeGenOpenCLCXX/addrspace-operators.clcpp (+2-2)
  • (modified) clang/test/CodeGenSYCL/field-annotate-addr-space.cpp (+1-1)
  • (modified) clang/test/OpenMP/atomic_capture_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/atomic_update_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/bug57757.cpp (+4-4)
  • (modified) clang/test/OpenMP/cancel_codegen.cpp (+47-47)
  • (modified) clang/test/OpenMP/cancellation_point_codegen.cpp (+37-37)
  • (modified) clang/test/OpenMP/critical_codegen.cpp (+2-2)
  • (modified) clang/test/OpenMP/critical_codegen_attr.cpp (+2-2)
  • (modified) clang/test/OpenMP/declare_mapper_codegen.cpp (+46-46)
  • (modified) clang/test/OpenMP/depobj_codegen.cpp (+22-22)
  • (modified) clang/test/OpenMP/distribute_firstprivate_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/distribute_lastprivate_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/distribute_parallel_for_codegen.cpp (+66-66)
  • (modified) clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp (+8-8)
  • (modified) clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp (+16-16)
  • (modified) clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp (+31-31)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_codegen.cpp (+76-76)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp (+12-12)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp (+24-24)
  • (modified) clang/test/OpenMP/distribute_private_codegen.cpp (+16-16)
  • (modified) clang/test/OpenMP/distribute_simd_firstprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/distribute_simd_lastprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/distribute_simd_private_codegen.cpp (+24-24)
  • (modified) clang/test/OpenMP/distribute_simd_reduction_codegen.cpp (+1-1)
  • (modified) clang/test/OpenMP/for_firstprivate_codegen.cpp (+34-34)
  • (modified) clang/test/OpenMP/for_lastprivate_codegen.cpp (+113-113)
  • (modified) clang/test/OpenMP/for_linear_codegen.cpp (+62-62)
  • (modified) clang/test/OpenMP/for_private_codegen.cpp (+17-17)
  • (modified) clang/test/OpenMP/for_reduction_codegen.cpp (+13-13)
  • (modified) clang/test/OpenMP/for_reduction_codegen_UDR.cpp (+16-16)
  • (modified) clang/test/OpenMP/for_reduction_task_codegen.cpp (+47-47)
  • (modified) clang/test/OpenMP/interop_irbuilder.cpp (+49-49)
  • (modified) clang/test/OpenMP/irbuilder_for_iterator.cpp (+28-28)
  • (modified) clang/test/OpenMP/irbuilder_for_rangefor.cpp (+28-28)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_auto.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_down.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_dynamic.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_dynamic_chunked.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_runtime.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_static_chunked.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_nested_parallel_for.c (+80-80)
  • (modified) clang/test/OpenMP/irbuilder_safelen.cpp (+22-22)
  • (modified) clang/test/OpenMP/irbuilder_safelen_order_concurrent.cpp (+24-24)
  • (modified) clang/test/OpenMP/irbuilder_simd.cpp (+3-3)
  • (modified) clang/test/OpenMP/irbuilder_simd_aligned.cpp (+26-26)
  • (modified) clang/test/OpenMP/irbuilder_simdlen.cpp (+24-24)
  • (modified) clang/test/OpenMP/irbuilder_simdlen_safelen.cpp (+22-22)
  • (modified) clang/test/OpenMP/irbuilder_unroll_full.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_unroll_heuristic.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_unroll_partial_factor.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_unroll_partial_factor_for.c (+6-6)
  • (modified) clang/test/OpenMP/irbuilder_unroll_partial_heuristic.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_unroll_unroll_partial_factor.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_unroll_unroll_partial_heuristic.c (+4-4)
  • (modified) clang/test/OpenMP/loops_explicit_clauses_codegen.cpp (+19-19)
  • (modified) clang/test/OpenMP/map_struct_ordering.cpp (+9-9)
  • (modified) clang/test/OpenMP/master_taskloop_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/master_taskloop_firstprivate_codegen.cpp (+57-57)
  • (modified) clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp (+63-63)
  • (modified) clang/test/OpenMP/master_taskloop_lastprivate_codegen.cpp (+57-57)
  • (modified) clang/test/OpenMP/master_taskloop_private_codegen.cpp (+44-44)
  • (modified) clang/test/OpenMP/master_taskloop_reduction_codegen.cpp (+28-28)
  • (modified) clang/test/OpenMP/master_taskloop_simd_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/master_taskloop_simd_firstprivate_codegen.cpp (+57-57)
  • (modified) clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp (+64-64)
  • (modified) clang/test/OpenMP/master_taskloop_simd_lastprivate_codegen.cpp (+57-57)
  • (modified) clang/test/OpenMP/master_taskloop_simd_private_codegen.cpp (+44-44)
  • (modified) clang/test/OpenMP/master_taskloop_simd_reduction_codegen.cpp (+28-28)
  • (modified) clang/test/OpenMP/nested_loop_codegen.cpp (+16-16)
  • (modified) clang/test/OpenMP/nvptx_lambda_pointer_capturing.cpp (+7-7)
  • (modified) clang/test/OpenMP/nvptx_target_codegen.cpp (+14-14)
  • (modified) clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp (+322-322)
  • (modified) clang/test/OpenMP/ordered_doacross_codegen.c (+2-2)
  • (modified) clang/test/OpenMP/ordered_doacross_codegen.cpp (+8-8)
  • (modified) clang/test/OpenMP/parallel_copyin_codegen.cpp (+12-12)
  • (modified) clang/test/OpenMP/parallel_firstprivate_codegen.cpp (+161-161)
  • (modified) clang/test/OpenMP/parallel_for_lastprivate_conditional.cpp (+6-6)
  • (modified) clang/test/OpenMP/parallel_for_linear_codegen.cpp (+12-12)
  • (modified) clang/test/OpenMP/parallel_for_reduction_task_codegen.cpp (+47-47)
  • (modified) clang/test/OpenMP/parallel_master_codegen.cpp (+14-14)
  • (modified) clang/test/OpenMP/parallel_master_reduction_task_codegen.cpp (+47-47)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_codegen.cpp (+234-234)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp (+169-169)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp (+182-182)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_private_codegen.cpp (+40-40)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_reduction_codegen.cpp (+28-28)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_simd_codegen.cpp (+231-231)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp (+169-169)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp (+192-192)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_simd_private_codegen.cpp (+40-40)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_simd_reduction_codegen.cpp (+28-28)
  • (modified) clang/test/OpenMP/parallel_private_codegen.cpp (+44-44)
  • (modified) clang/test/OpenMP/parallel_reduction_codegen.cpp (+84-84)
  • (modified) clang/test/OpenMP/parallel_reduction_task_codegen.cpp (+47-47)
  • (modified) clang/test/OpenMP/parallel_sections_reduction_task_codegen.cpp (+48-48)
  • (modified) clang/test/OpenMP/reduction_compound_op.cpp (+98-98)
  • (modified) clang/test/OpenMP/reduction_implicit_map.cpp (+38-38)
  • (modified) clang/test/OpenMP/reverse_codegen.cpp (+6-5)
  • (modified) clang/test/OpenMP/sections_firstprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/sections_lastprivate_codegen.cpp (+26-26)
  • (modified) clang/test/OpenMP/sections_private_codegen.cpp (+13-13)
  • (modified) clang/test/OpenMP/sections_reduction_codegen.cpp (+11-11)
  • (modified) clang/test/OpenMP/sections_reduction_task_codegen.cpp (+48-48)
  • (modified) clang/test/OpenMP/simd_private_taskloop_codegen.cpp (+196-196)
  • (modified) clang/test/OpenMP/single_codegen.cpp (+662-662)
  • (modified) clang/test/OpenMP/single_firstprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/single_private_codegen.cpp (+13-13)
  • (modified) clang/test/OpenMP/target_codegen.cpp (+10-10)
  • (modified) clang/test/OpenMP/target_data_map_codegen_hold.cpp (+44-44)
  • (modified) clang/test/OpenMP/target_data_no_device_codegen.cpp (+2-2)
  • (modified) clang/test/OpenMP/target_data_use_device_addr_codegen.cpp (+8-8)
  • (modified) clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp (+5-5)
  • (modified) clang/test/OpenMP/target_data_use_device_ptr_inheritance_codegen.cpp (+14-14)
  • (modified) clang/test/OpenMP/target_defaultmap_codegen_01.cpp (+8-8)
  • (modified) clang/test/OpenMP/target_defaultmap_codegen_02.cpp (+1-1)
  • (modified) clang/test/OpenMP/target_depend_codegen.cpp (+14-14)
diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h
index 5d59d5a4ae2c1..66bd2e4d36d3f 100644
--- a/clang/lib/CodeGen/CGBuilder.h
+++ b/clang/lib/CodeGen/CGBuilder.h
@@ -210,10 +210,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
   /// Given
   ///   %addr = {T1, T2...}* ...
   /// produce
-  ///   %name = getelementptr inbounds %addr, i32 0, i32 index
+  ///   %name = getelementptr inbounds nuw %addr, i32 0, i32 index
   ///
   /// This API assumes that drilling into a struct like this is always an
-  /// inbounds operation.
+  /// inbounds and nuw operation.
   using CGBuilderBaseTy::CreateStructGEP;
   Address CreateStructGEP(Address Addr, unsigned Index,
                           const llvm::Twine &Name = "") {
@@ -222,7 +222,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
     const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
     auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
 
-    return Address(CreateStructGEP(Addr.getElementType(), Addr.getBasePointer(),
+    return Address(CreateNUWStructGEP(Addr.getElementType(), Addr.getBasePointer(),
                                    Index, Name),
                    ElTy->getElementType(Index),
                    Addr.getAlignment().alignmentAtOffset(Offset),
diff --git a/clang/test/C/C2y/n3254.c b/clang/test/C/C2y/n3254.c
index 60d068cf9980b..e114735a9cb79 100644
--- a/clang/test/C/C2y/n3254.c
+++ b/clang/test/C/C2y/n3254.c
@@ -27,7 +27,7 @@ struct S {
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
 // CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[S_PTR]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 8
-// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 0
+// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 0
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[X]], align 4
 // CHECK-NEXT:    ret i32 [[TMP1]]
 //
@@ -42,10 +42,10 @@ int foo() {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 4
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 1
+// CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 1
 // CHECK-NEXT:    store i8 97, ptr [[C]], align 4
 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[C2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 1
+// CHECK-NEXT:    [[C2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 1
 // CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[C2]], align 4
 // CHECK-NEXT:    ret i8 [[TMP0]]
 //
@@ -60,10 +60,10 @@ char bar() {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 4
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 2
+// CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 2
 // CHECK-NEXT:    store float 3.000000e+00, ptr [[F]], align 4
 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 2
+// CHECK-NEXT:    [[F2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 2
 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[F2]], align 4
 // CHECK-NEXT:    ret float [[TMP0]]
 //
@@ -83,11 +83,11 @@ struct T {
 // CHECK-NEXT:    [[T:%.*]] = alloca [[STRUCT_T:%.*]], align 4
 // CHECK-NEXT:    [[S_PTR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[T]], i8 0, i64 12, i1 false)
-// CHECK-NEXT:    [[BUFFER:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[T]], i32 0, i32 0
+// CHECK-NEXT:    [[BUFFER:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[T]], i32 0, i32 0
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
 // CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[S_PTR]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 8
-// CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 1
+// CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 1
 // CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[C]], align 4
 // CHECK-NEXT:    ret i8 [[TMP1]]
 //
@@ -107,11 +107,11 @@ char quux() {
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
 // CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[T_PTR]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[T_PTR]], align 8
-// CHECK-NEXT:    [[BUFFER1:%.*]] = getelementptr inbounds [[STRUCT_T:%.*]], ptr [[TMP0]], i32 0, i32 0
+// CHECK-NEXT:    [[BUFFER1:%.*]] = getelementptr inbounds nuw [[STRUCT_T:%.*]], ptr [[TMP0]], i32 0, i32 0
 // CHECK-NEXT:    [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER1]], i64 0, i64 0
 // CHECK-NEXT:    store ptr [[ARRAYDECAY2]], ptr [[S_PTR]], align 8
 // CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[S_PTR]], align 8
-// CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP1]], i32 0, i32 2
+// CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP1]], i32 0, i32 2
 // CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[F]], align 4
 // CHECK-NEXT:    ret float [[TMP2]]
 //
@@ -128,16 +128,16 @@ float quibble() {
 // CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 4
 // CHECK-NEXT:    [[S_PTR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[BUFFER1:%.*]] = getelementptr inbounds [[STRUCT_T:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 0
+// CHECK-NEXT:    [[BUFFER1:%.*]] = getelementptr inbounds nuw [[STRUCT_T:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 0
 // CHECK-NEXT:    [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER1]], i64 0, i64 0
-// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY2]], i32 0, i32 0
+// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY2]], i32 0, i32 0
 // CHECK-NEXT:    store i32 12, ptr [[X]], align 4
 // CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[BUFFER4:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[ARRAYDECAY3]], i32 0, i32 0
+// CHECK-NEXT:    [[BUFFER4:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[ARRAYDECAY3]], i32 0, i32 0
 // CHECK-NEXT:    [[ARRAYDECAY5:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER4]], i64 0, i64 0
 // CHECK-NEXT:    store ptr [[ARRAYDECAY5]], ptr [[S_PTR]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 8
-// CHECK-NEXT:    [[X6:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[TMP0]], i32 0, i32 0
+// CHECK-NEXT:    [[X6:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[TMP0]], i32 0, i32 0
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[X6]], align 4
 // CHECK-NEXT:    ret i32 [[TMP1]]
 //
diff --git a/clang/test/C/C2y/n3259.c b/clang/test/C/C2y/n3259.c
index 42c6720b2a665..2e94e3fc971df 100644
--- a/clang/test/C/C2y/n3259.c
+++ b/clang/test/C/C2y/n3259.c
@@ -12,52 +12,52 @@ void test() {
   // CHECK: store float 0
   _Complex float f = __builtin_complex(1.0f, 0.0f);
 
-  // CHECK:      %[[F_REALP1:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK:      %[[F_REALP1:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
   // CHECK-NEXT: %[[F_REAL:.+]] = load float, ptr %[[F_REALP1]]
-  // CHECK-NEXT: %[[F_IMAGP2:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_IMAGP2:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: %[[F_IMAG:.+]] = load float, ptr %[[F_IMAGP2]]
   // CHECK-NEXT: %[[INC:.+]] = fadd float %[[F_REAL]], 1.000000e+00
-  // CHECK-NEXT: %[[F_REALP3:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
-  // CHECK-NEXT: %[[F_IMAGP4:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_REALP3:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK-NEXT: %[[F_IMAGP4:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: store float %[[INC]], ptr %[[F_REALP3]]
   // CHECK-NEXT: store float %[[F_IMAG]], ptr %[[F_IMAGP4]]
   f++; /* expected-warning {{'++' on an object of complex type is a C2y extension}}
           pre-c2y-warning {{'++' on an object of complex type is incompatible with C standards before C2y}}
         */
 
-  // CHECK:      %[[F_REALP5:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK:      %[[F_REALP5:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
   // CHECK-NEXT: %[[F_REAL6:.+]] = load float, ptr %[[F_REALP5]]
-  // CHECK-NEXT: %[[F_IMAGP7:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_IMAGP7:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: %[[F_IMAG8:.+]] = load float, ptr %[[F_IMAGP7]]
   // CHECK-NEXT: %[[INC9:.+]] = fadd float %[[F_REAL6]], 1.000000e+00
-  // CHECK-NEXT: %[[F_REALP10:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
-  // CHECK-NEXT: %[[F_IMAGP11:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_REALP10:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK-NEXT: %[[F_IMAGP11:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: store float %[[INC9]], ptr %[[F_REALP10]]
   // CHECK-NEXT: store float %[[F_IMAG8]], ptr %[[F_IMAGP11]]
   ++f; /* expected-warning {{'++' on an object of complex type is a C2y extension}}
           pre-c2y-warning {{'++' on an object of complex type is incompatible with C standards before C2y}}
         */
 
-  // CHECK:      %[[F_REALP12:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK:      %[[F_REALP12:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
   // CHECK-NEXT: %[[F_REAL13:.+]] = load float, ptr %[[F_REALP12]]
-  // CHECK-NEXT: %[[F_IMAGP14:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_IMAGP14:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: %[[F_IMAG15:.+]] = load float, ptr %[[F_IMAGP14]]
   // CHECK-NEXT: %[[DEC:.+]] = fadd float %[[F_REAL13]], -1.000000e+00
-  // CHECK-NEXT: %[[F_REALP16:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
-  // CHECK-NEXT: %[[F_IMAGP17:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_REALP16:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK-NEXT: %[[F_IMAGP17:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: store float %[[DEC]], ptr %[[F_REALP16]]
   // CHECK-NEXT: store float %[[F_IMAG15]], ptr %[[F_IMAGP17]]
   f--; /* expected-warning {{'--' on an object of complex type is a C2y extension}}
           pre-c2y-warning {{'--' on an object of complex type is incompatible with C standards before C2y}}
         */
 
-  // CHECK:      %[[F_REALP18:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK:      %[[F_REALP18:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
   // CHECK-NEXT: %[[F_REAL19:.+]] = load float, ptr %[[F_REALP18]]
-  // CHECK-NEXT: %[[F_IMAGP20:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_IMAGP20:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: %[[F_IMAG21:.+]] = load float, ptr %[[F_IMAGP20]]
   // CHECK-NEXT: %[[DEC22:.+]] = fadd float %[[F_REAL19]], -1.000000e+00
-  // CHECK-NEXT: %[[F_REALP23:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
-  // CHECK-NEXT: %[[F_IMAGP24:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_REALP23:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK-NEXT: %[[F_IMAGP24:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: store float %[[DEC22]], ptr %[[F_REALP23]]
   // CHECK-NEXT: store float %[[F_IMAG21]], ptr %[[F_IMAGP24]]
   --f; /* expected-warning {{'--' on an object of complex type is a C2y extension}}
diff --git a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
index 82b5ac0fdc06c..8911257741c33 100644
--- a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
+++ b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
@@ -10,8 +10,8 @@ _Complex float foo1(_Complex float x) {
 // CHECK:                   ret { float, float }
 
 // PPC32LNX-LABEL:          define{{.*}} void @foo1(ptr dead_on_unwind noalias writable sret({ float, float }) align 4 %agg.result, ptr noundef byval({ float, float }) align 4 %x) #0 {
-// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds { float, float }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds { float, float }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 1
 // PPC32LNX-NEXT:           store float %{{.*}}, ptr [[RETREAL]], align 4
 // PPC32LNX-NEXT:           store float %{{.*}}, ptr [[RETIMAG]], align 4
 }
@@ -22,8 +22,8 @@ _Complex double foo2(_Complex double x) {
 // CHECK:                   ret { double, double }
 
 // PPC32LNX-LABEL:          define{{.*}} void @foo2(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result, ptr noundef byval({ double, double }) align 8 %x) #0 {
-// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds { double, double }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds { double, double }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 1
 // PPC32LNX-NEXT:           store double %{{.*}}, ptr [[RETREAL]], align 8
 // PPC32LNX-NEXT:           store double %{{.*}}, ptr [[RETIMAG]], align 8
 }
@@ -37,8 +37,8 @@ _Complex long double foo3(_Complex long double x) {
 // CHECK-LDBL128:           ret { ppc_fp128, ppc_fp128 }
 
 // PPC32LNX-LABEL:          define{{.*}} void @foo3(ptr dead_on_unwind noalias writable sret({ ppc_fp128, ppc_fp128 }) align 16 %agg.result, ptr noundef byval({ ppc_fp128, ppc_fp128 }) align 16 %x) #0 {
-// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 1
 // PPC32LNX-NEXT:           store ppc_fp128 %{{.*}}, ptr [[RETREAL]], align 16
 // PPC32LNX-NEXT:           store ppc_fp128 %{{.*}}, ptr [[RETIMAG]], align 16
 }
diff --git a/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c b/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c
index 2f5459d1bb9c4..08d3d2a9cc3c3 100644
--- a/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c
+++ b/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c
@@ -93,7 +93,7 @@ void long_double(int n, ...) {
 // IEEE: %[[V0:[0-9a-zA-Z_.]+]] = getelementptr inbounds i8, ptr %[[ALIGN]], i64 16
 // IEEE: store ptr %[[V0]], ptr %[[AP]], align 8
 // IEEE: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %[[TMP:[0-9a-zA-Z_.]+]], ptr align 16 %[[ALIGN]], i64 16, i1 false)
-// IEEE: %[[COERCE:[0-9a-zA-Z_.]+]] = getelementptr inbounds %struct.ldbl128_s, ptr %[[TMP]], i32 0, i32 0
+// IEEE: %[[COERCE:[0-9a-zA-Z_.]+]] = getelementptr inbounds nuw %struct.ldbl128_s, ptr %[[TMP]], i32 0, i32 0
 // IEEE: %[[V4:[0-9a-zA-Z_.]+]] = load fp128, ptr %[[COERCE]], align 16
 // IEEE: call void @foo_ls(fp128 inreg %[[V4]])
 // IEEE: call void @llvm.va_end.p0(ptr %[[AP]])
diff --git a/clang/test/CodeGen/RISCV/bfloat-abi.c b/clang/test/CodeGen/RISCV/bfloat-abi.c
index f38646c8b12ff..f7c82adaa6d89 100644
--- a/clang/test/CodeGen/RISCV/bfloat-abi.c
+++ b/clang/test/CodeGen/RISCV/bfloat-abi.c
@@ -14,9 +14,9 @@ struct bfloat1 {
 // CHECK-RV64-NEXT:    [[COERCE_DIVE_COERCE:%.*]] = alloca i64, align 8
 // CHECK-RV64-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2
 // CHECK-RV64-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2
-// CHECK-RV64-NEXT:    [[A1:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
+// CHECK-RV64-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
 // CHECK-RV64-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 2
-// CHECK-RV64-NEXT:    [[COERCE_DIVE:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
+// CHECK-RV64-NEXT:    [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
 // CHECK-RV64-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[COERCE_DIVE_COERCE]], ptr align 2 [[COERCE_DIVE]], i64 2, i1 false)
 // CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[COERCE_DIVE_COERCE]], align 8
 // CHECK-RV64-NEXT:    ret i64 [[TMP1]]
@@ -29,9 +29,9 @@ struct bfloat1 {
 // CHECK-RV32-NEXT:    [[COERCE_DIVE_COERCE:%.*]] = alloca i32, align 4
 // CHECK-RV32-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2
 // CHECK-RV32-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2
-// CHECK-RV32-NEXT:    [[A1:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
+// CHECK-RV32-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
 // CHECK-RV32-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 2
-// CHECK-RV32-NEXT:    [[COERCE_DIVE:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
+// CHECK-RV32-NEXT:    [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
 // CHECK-RV32-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[COERCE_DIVE_COERCE]], ptr align 2 [[COERCE_DIVE]], i32 2, i1 false)
 // CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[COERCE_DIVE_COERCE]], align 4
 // CHECK-RV32-NEXT:    ret i32 [[TMP1]]
@@ -57,10 +57,10 @@ struct bfloat2 {
 // CHECK-RV64-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2
 // CHECK-RV64-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2
 // CHECK-RV64-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2
-// CHECK-RV64-NEXT:    [[A1:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT2]], ptr [[RETVAL]], i32 0, i32 0
+// CHECK-RV64-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT2]], ptr [[RETVAL]], i32 0, i32 0
 // CHECK-RV64-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 2
 // CHECK-RV64-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2
-// CHECK-RV64-NEXT:    [[B2:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT2]], ptr [[RETVAL]], i32 0, i32 1
+// CHECK-RV64-NEXT:    [[B2...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Jul 18, 2024

@llvm/pr-subscribers-backend-risc-v

Author: Hari Limaye (hazzlim)

Changes

Generate nuw GEPs for struct member accesses, as these are always constant positive offsets derived from the index of the struct member.

Regression tests are updated using update_cc_test_checks.py where possible, and by find + replace where not.


Patch is 7.54 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/99538.diff

456 Files Affected:

  • (modified) clang/lib/CodeGen/CGBuilder.h (+3-3)
  • (modified) clang/test/C/C2y/n3254.c (+13-13)
  • (modified) clang/test/C/C2y/n3259.c (+16-16)
  • (modified) clang/test/CodeGen/PowerPC/powerpc-c99complex.c (+6-6)
  • (modified) clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c (+1-1)
  • (modified) clang/test/CodeGen/RISCV/bfloat-abi.c (+60-60)
  • (modified) clang/test/CodeGen/RISCV/riscv32-vararg.c (+42-42)
  • (modified) clang/test/CodeGen/RISCV/riscv64-vararg.c (+27-27)
  • (modified) clang/test/CodeGen/SystemZ/systemz-abi-vector.c (+52-52)
  • (modified) clang/test/CodeGen/SystemZ/systemz-abi.c (+61-61)
  • (modified) clang/test/CodeGen/X86/Float16-arithmetic.c (+25-25)
  • (modified) clang/test/CodeGen/X86/Float16-complex.c (+328-328)
  • (modified) clang/test/CodeGen/X86/cx-complex-range.c (+197-192)
  • (modified) clang/test/CodeGen/X86/va-arg-sse.c (+25-25)
  • (modified) clang/test/CodeGen/X86/x86_64-floatvectors.c (+14-14)
  • (modified) clang/test/CodeGen/X86/x86_64-vaarg.c (+5-5)
  • (modified) clang/test/CodeGen/aapcs-bitfield.c (+216-216)
  • (modified) clang/test/CodeGen/aarch64-neon-intrinsics.c (+360-360)
  • (modified) clang/test/CodeGen/aarch64-neon-ldst-one.c (+672-672)
  • (modified) clang/test/CodeGen/aarch64-neon-perm.c (+54-54)
  • (modified) clang/test/CodeGen/aarch64-neon-tbl.c (+156-156)
  • (modified) clang/test/CodeGen/aarch64-poly64.c (+24-24)
  • (modified) clang/test/CodeGen/aarch64-soft-float-abi.c (+4-4)
  • (modified) clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-generic.c (+6-6)
  • (modified) clang/test/CodeGen/address-space-field1.c (+4-4)
  • (modified) clang/test/CodeGen/align_value.cpp (+2-2)
  • (modified) clang/test/CodeGen/alloc-align-attr.c (+31-31)
  • (modified) clang/test/CodeGen/annotations-field.c (+1-1)
  • (modified) clang/test/CodeGen/arm-neon-vst.c (+288-288)
  • (modified) clang/test/CodeGen/arm-swiftcall.c (+78-78)
  • (modified) clang/test/CodeGen/arm-varargs.c (+2-2)
  • (modified) clang/test/CodeGen/arm64-arguments.c (+48-48)
  • (modified) clang/test/CodeGen/arm64-be-bitfield.c (+1-1)
  • (modified) clang/test/CodeGen/arm64-be-hfa-vararg.c (+2-2)
  • (modified) clang/test/CodeGen/arm_neon_intrinsics.c (+708-708)
  • (modified) clang/test/CodeGen/attr-arm-sve-vector-bits-bitcast.c (+24-24)
  • (modified) clang/test/CodeGen/attr-counted-by-pr88931.c (+1-1)
  • (modified) clang/test/CodeGen/attr-counted-by.c (+50-50)
  • (modified) clang/test/CodeGen/block-byref-aggr.c (+8-8)
  • (modified) clang/test/CodeGen/blocks-seq.c (+2-2)
  • (modified) clang/test/CodeGen/blocks.c (+4-4)
  • (modified) clang/test/CodeGen/builtin-complex.c (+2-2)
  • (modified) clang/test/CodeGen/builtin-dump-struct.c (+31-31)
  • (modified) clang/test/CodeGen/builtins.c (+4-4)
  • (modified) clang/test/CodeGen/c11atomics-ios.c (+30-30)
  • (modified) clang/test/CodeGen/c11atomics.c (+32-32)
  • (modified) clang/test/CodeGen/capture-complex-expr-in-block.c (+2-2)
  • (modified) clang/test/CodeGen/captured-statements-nested.c (+20-20)
  • (modified) clang/test/CodeGen/captured-statements.c (+2-2)
  • (modified) clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-lvalue.cpp (+1-1)
  • (modified) clang/test/CodeGen/complex-convert.c (+176-176)
  • (modified) clang/test/CodeGen/compound-literal.c (+7-7)
  • (modified) clang/test/CodeGen/cx-complex-range.c (+764-764)
  • (modified) clang/test/CodeGen/ext-int.c (+9-9)
  • (modified) clang/test/CodeGen/matrix-type-builtins.c (+2-2)
  • (modified) clang/test/CodeGen/matrix-type.c (+2-2)
  • (modified) clang/test/CodeGen/ms-anonymous-struct.c (+24-24)
  • (modified) clang/test/CodeGen/packed-structure.c (+1-1)
  • (modified) clang/test/CodeGen/paren-list-agg-init.cpp (+41-41)
  • (modified) clang/test/CodeGen/pragma-cx-limited-range.c (+2-2)
  • (modified) clang/test/CodeGen/smiths-complex-div.c (+6-6)
  • (modified) clang/test/CodeGen/transparent-union-redecl.c (+3-3)
  • (modified) clang/test/CodeGen/unaligned-expr.c (+2-2)
  • (modified) clang/test/CodeGen/variadic-gpfp-x86.c (+1-1)
  • (modified) clang/test/CodeGen/variadic-nvptx.c (+9-9)
  • (modified) clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp (+3-3)
  • (modified) clang/test/CodeGen/windows-swiftcall.c (+56-56)
  • (modified) clang/test/CodeGenCUDA/lambda-reference-var.cu (+3-3)
  • (modified) clang/test/CodeGenCUDA/record-layout.cu (+6-6)
  • (modified) clang/test/CodeGenCXX/RelativeVTablesABI/type-info.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/alignment.cpp (+8-8)
  • (modified) clang/test/CodeGenCXX/arm-swiftcall.cpp (+16-16)
  • (modified) clang/test/CodeGenCXX/asm.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/attr-annotate.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp (+9-9)
  • (modified) clang/test/CodeGenCXX/auto-var-init.cpp (+24-24)
  • (modified) clang/test/CodeGenCXX/bitfield-ir.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/bitfield.cpp (+16-16)
  • (modified) clang/test/CodeGenCXX/block-capture.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/block-inalloca.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/blocks-cxx11.cpp (+4-4)
  • (modified) clang/test/CodeGenCXX/blocks.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/builtin-dump-struct.cpp (+8-8)
  • (modified) clang/test/CodeGenCXX/captured-statements.cpp (+6-6)
  • (modified) clang/test/CodeGenCXX/catch-undef-behavior.cpp (+4-4)
  • (modified) clang/test/CodeGenCXX/copy-constructor-synthesis.cpp (+4-4)
  • (modified) clang/test/CodeGenCXX/cxx11-initializer-aggregate.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp (+6-6)
  • (modified) clang/test/CodeGenCXX/cxx1z-lambda-star-this.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/cxx20-consteval-crash.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/cxx20-decomposition.cpp (+6-6)
  • (modified) clang/test/CodeGenCXX/cxx2a-compare.cpp (+5-5)
  • (modified) clang/test/CodeGenCXX/cxx2a-consteval.cpp (+10-10)
  • (modified) clang/test/CodeGenCXX/cxx2b-deducing-this.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/debug-info-lambda.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp (+7-7)
  • (modified) clang/test/CodeGenCXX/decl-ref-inheritance.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/eh-aggregated-inits-unwind.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/exceptions.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/ext-int.cpp (+9-9)
  • (modified) clang/test/CodeGenCXX/ibm128-declarations.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/inalloca-lambda.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/inalloca-overaligned.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/inalloca-vector.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/lambda-deterministic-captures.cpp (+6-6)
  • (modified) clang/test/CodeGenCXX/matrix-type-builtins.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/matrix-type-operators.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/matrix-type.cpp (+9-9)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp (+6-6)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-explicit-object-parameters.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp (+5-5)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/new-array-init.cpp (+8-8)
  • (modified) clang/test/CodeGenCXX/noescape.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/nrvo.cpp (+158-158)
  • (modified) clang/test/CodeGenCXX/partial-destruction.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/pr20897.cpp (+4-4)
  • (modified) clang/test/CodeGenCXX/strict-vtable-pointers.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/temporaries.cpp (+3-3)
  • (modified) clang/test/CodeGenCXX/trivial-auto-var-init.cpp (+4-4)
  • (modified) clang/test/CodeGenCXX/trivial_abi.cpp (+9-9)
  • (modified) clang/test/CodeGenCXX/trivial_abi_debuginfo.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/ubsan-global-alignment.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp (+1-1)
  • (modified) clang/test/CodeGenCXX/virtual-bases.cpp (+2-2)
  • (modified) clang/test/CodeGenCXX/vla-lambda-capturing.cpp (+30-30)
  • (modified) clang/test/CodeGenCXX/x86_64-vaarg.cpp (+3-3)
  • (modified) clang/test/CodeGenCoroutines/coro-await.cpp (+1-1)
  • (modified) clang/test/CodeGenCoroutines/coro-params.cpp (+2-2)
  • (modified) clang/test/CodeGenHLSL/buffer-array-operator.hlsl (+2-2)
  • (modified) clang/test/CodeGenHLSL/this-assignment-overload.hlsl (+4-4)
  • (modified) clang/test/CodeGenHLSL/this-assignment.hlsl (+2-2)
  • (modified) clang/test/CodeGenHLSL/this-reference.hlsl (+2-2)
  • (modified) clang/test/CodeGenObjC/arc-blocks.m (+45-45)
  • (modified) clang/test/CodeGenObjC/arc-foreach.m (+8-8)
  • (modified) clang/test/CodeGenObjC/arc-unoptimized-byref-var.m (+2-2)
  • (modified) clang/test/CodeGenObjC/asm.m (+2-2)
  • (modified) clang/test/CodeGenObjC/block-6.m (+3-3)
  • (modified) clang/test/CodeGenObjC/blocks-2.m (+1-1)
  • (modified) clang/test/CodeGenObjC/blocks.m (+12-12)
  • (modified) clang/test/CodeGenObjC/category-super-class-meth.m (+1-1)
  • (modified) clang/test/CodeGenObjC/class-stubs.m (+2-2)
  • (modified) clang/test/CodeGenObjC/noescape.m (+6-6)
  • (modified) clang/test/CodeGenObjC/nontrivial-c-struct-property.m (+2-2)
  • (modified) clang/test/CodeGenObjC/nontrivial-struct-param-init.m (+1-1)
  • (modified) clang/test/CodeGenObjC/ns_consume_null_check.m (+4-4)
  • (modified) clang/test/CodeGenObjC/objc-dispatch-null-check.m (+2-2)
  • (modified) clang/test/CodeGenObjC/objc-non-trivial-struct-nrvo.m (+1-1)
  • (modified) clang/test/CodeGenObjC/property-array-type.m (+1-1)
  • (modified) clang/test/CodeGenObjC/strong-in-c-struct.m (+18-18)
  • (modified) clang/test/CodeGenObjCXX/arc-blocks.mm (+24-24)
  • (modified) clang/test/CodeGenObjCXX/arc-cxx11-init-list.mm (+1-1)
  • (modified) clang/test/CodeGenObjCXX/arc-cxx11-member-init.mm (+1-1)
  • (modified) clang/test/CodeGenObjCXX/arc-exceptions.mm (+2-2)
  • (modified) clang/test/CodeGenObjCXX/arc-indirect.mm (+1-1)
  • (modified) clang/test/CodeGenObjCXX/arc-special-member-functions.mm (+2-2)
  • (modified) clang/test/CodeGenObjCXX/block-default-arg.mm (+1-1)
  • (modified) clang/test/CodeGenObjCXX/block-nested-in-lambda.mm (+16-16)
  • (modified) clang/test/CodeGenObjCXX/gc.mm (+1-1)
  • (modified) clang/test/CodeGenObjCXX/lambda-expressions.mm (+5-5)
  • (modified) clang/test/CodeGenObjCXX/lambda-to-block.mm (+4-4)
  • (modified) clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm (+6-6)
  • (modified) clang/test/CodeGenObjCXX/property-object-conditional-exp.mm (+2-2)
  • (modified) clang/test/CodeGenObjCXX/property-objects.mm (+1-1)
  • (modified) clang/test/CodeGenOpenCL/addr-space-struct-arg.cl (+1-1)
  • (modified) clang/test/CodeGenOpenCL/amdgpu-abi-struct-arg-byref.cl (+24-24)
  • (modified) clang/test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl (+152-151)
  • (modified) clang/test/CodeGenOpenCL/blocks.cl (+10-10)
  • (modified) clang/test/CodeGenOpenCL/cl20-device-side-enqueue-attributes.cl (+30-30)
  • (modified) clang/test/CodeGenOpenCLCXX/addrspace-operators.clcpp (+2-2)
  • (modified) clang/test/CodeGenSYCL/field-annotate-addr-space.cpp (+1-1)
  • (modified) clang/test/OpenMP/atomic_capture_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/atomic_update_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/bug57757.cpp (+4-4)
  • (modified) clang/test/OpenMP/cancel_codegen.cpp (+47-47)
  • (modified) clang/test/OpenMP/cancellation_point_codegen.cpp (+37-37)
  • (modified) clang/test/OpenMP/critical_codegen.cpp (+2-2)
  • (modified) clang/test/OpenMP/critical_codegen_attr.cpp (+2-2)
  • (modified) clang/test/OpenMP/declare_mapper_codegen.cpp (+46-46)
  • (modified) clang/test/OpenMP/depobj_codegen.cpp (+22-22)
  • (modified) clang/test/OpenMP/distribute_firstprivate_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/distribute_lastprivate_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/distribute_parallel_for_codegen.cpp (+66-66)
  • (modified) clang/test/OpenMP/distribute_parallel_for_firstprivate_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/distribute_parallel_for_lastprivate_codegen.cpp (+20-20)
  • (modified) clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp (+8-8)
  • (modified) clang/test/OpenMP/distribute_parallel_for_private_codegen.cpp (+16-16)
  • (modified) clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp (+31-31)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_codegen.cpp (+76-76)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_firstprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_lastprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp (+12-12)
  • (modified) clang/test/OpenMP/distribute_parallel_for_simd_private_codegen.cpp (+24-24)
  • (modified) clang/test/OpenMP/distribute_private_codegen.cpp (+16-16)
  • (modified) clang/test/OpenMP/distribute_simd_firstprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/distribute_simd_lastprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/distribute_simd_private_codegen.cpp (+24-24)
  • (modified) clang/test/OpenMP/distribute_simd_reduction_codegen.cpp (+1-1)
  • (modified) clang/test/OpenMP/for_firstprivate_codegen.cpp (+34-34)
  • (modified) clang/test/OpenMP/for_lastprivate_codegen.cpp (+113-113)
  • (modified) clang/test/OpenMP/for_linear_codegen.cpp (+62-62)
  • (modified) clang/test/OpenMP/for_private_codegen.cpp (+17-17)
  • (modified) clang/test/OpenMP/for_reduction_codegen.cpp (+13-13)
  • (modified) clang/test/OpenMP/for_reduction_codegen_UDR.cpp (+16-16)
  • (modified) clang/test/OpenMP/for_reduction_task_codegen.cpp (+47-47)
  • (modified) clang/test/OpenMP/interop_irbuilder.cpp (+49-49)
  • (modified) clang/test/OpenMP/irbuilder_for_iterator.cpp (+28-28)
  • (modified) clang/test/OpenMP/irbuilder_for_rangefor.cpp (+28-28)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_auto.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_down.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_dynamic.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_dynamic_chunked.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_runtime.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_for_unsigned_static_chunked.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_nested_parallel_for.c (+80-80)
  • (modified) clang/test/OpenMP/irbuilder_safelen.cpp (+22-22)
  • (modified) clang/test/OpenMP/irbuilder_safelen_order_concurrent.cpp (+24-24)
  • (modified) clang/test/OpenMP/irbuilder_simd.cpp (+3-3)
  • (modified) clang/test/OpenMP/irbuilder_simd_aligned.cpp (+26-26)
  • (modified) clang/test/OpenMP/irbuilder_simdlen.cpp (+24-24)
  • (modified) clang/test/OpenMP/irbuilder_simdlen_safelen.cpp (+22-22)
  • (modified) clang/test/OpenMP/irbuilder_unroll_full.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_unroll_heuristic.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_unroll_partial_factor.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_unroll_partial_factor_for.c (+6-6)
  • (modified) clang/test/OpenMP/irbuilder_unroll_partial_heuristic.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_unroll_unroll_partial_factor.c (+4-4)
  • (modified) clang/test/OpenMP/irbuilder_unroll_unroll_partial_heuristic.c (+4-4)
  • (modified) clang/test/OpenMP/loops_explicit_clauses_codegen.cpp (+19-19)
  • (modified) clang/test/OpenMP/map_struct_ordering.cpp (+9-9)
  • (modified) clang/test/OpenMP/master_taskloop_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/master_taskloop_firstprivate_codegen.cpp (+57-57)
  • (modified) clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp (+63-63)
  • (modified) clang/test/OpenMP/master_taskloop_lastprivate_codegen.cpp (+57-57)
  • (modified) clang/test/OpenMP/master_taskloop_private_codegen.cpp (+44-44)
  • (modified) clang/test/OpenMP/master_taskloop_reduction_codegen.cpp (+28-28)
  • (modified) clang/test/OpenMP/master_taskloop_simd_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/master_taskloop_simd_firstprivate_codegen.cpp (+57-57)
  • (modified) clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp (+64-64)
  • (modified) clang/test/OpenMP/master_taskloop_simd_lastprivate_codegen.cpp (+57-57)
  • (modified) clang/test/OpenMP/master_taskloop_simd_private_codegen.cpp (+44-44)
  • (modified) clang/test/OpenMP/master_taskloop_simd_reduction_codegen.cpp (+28-28)
  • (modified) clang/test/OpenMP/nested_loop_codegen.cpp (+16-16)
  • (modified) clang/test/OpenMP/nvptx_lambda_pointer_capturing.cpp (+7-7)
  • (modified) clang/test/OpenMP/nvptx_target_codegen.cpp (+14-14)
  • (modified) clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp (+322-322)
  • (modified) clang/test/OpenMP/ordered_doacross_codegen.c (+2-2)
  • (modified) clang/test/OpenMP/ordered_doacross_codegen.cpp (+8-8)
  • (modified) clang/test/OpenMP/parallel_copyin_codegen.cpp (+12-12)
  • (modified) clang/test/OpenMP/parallel_firstprivate_codegen.cpp (+161-161)
  • (modified) clang/test/OpenMP/parallel_for_lastprivate_conditional.cpp (+6-6)
  • (modified) clang/test/OpenMP/parallel_for_linear_codegen.cpp (+12-12)
  • (modified) clang/test/OpenMP/parallel_for_reduction_task_codegen.cpp (+47-47)
  • (modified) clang/test/OpenMP/parallel_master_codegen.cpp (+14-14)
  • (modified) clang/test/OpenMP/parallel_master_reduction_task_codegen.cpp (+47-47)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_codegen.cpp (+234-234)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp (+169-169)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp (+182-182)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_private_codegen.cpp (+40-40)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_reduction_codegen.cpp (+28-28)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_simd_codegen.cpp (+231-231)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp (+169-169)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp (+192-192)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_simd_private_codegen.cpp (+40-40)
  • (modified) clang/test/OpenMP/parallel_master_taskloop_simd_reduction_codegen.cpp (+28-28)
  • (modified) clang/test/OpenMP/parallel_private_codegen.cpp (+44-44)
  • (modified) clang/test/OpenMP/parallel_reduction_codegen.cpp (+84-84)
  • (modified) clang/test/OpenMP/parallel_reduction_task_codegen.cpp (+47-47)
  • (modified) clang/test/OpenMP/parallel_sections_reduction_task_codegen.cpp (+48-48)
  • (modified) clang/test/OpenMP/reduction_compound_op.cpp (+98-98)
  • (modified) clang/test/OpenMP/reduction_implicit_map.cpp (+38-38)
  • (modified) clang/test/OpenMP/reverse_codegen.cpp (+6-5)
  • (modified) clang/test/OpenMP/sections_firstprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/sections_lastprivate_codegen.cpp (+26-26)
  • (modified) clang/test/OpenMP/sections_private_codegen.cpp (+13-13)
  • (modified) clang/test/OpenMP/sections_reduction_codegen.cpp (+11-11)
  • (modified) clang/test/OpenMP/sections_reduction_task_codegen.cpp (+48-48)
  • (modified) clang/test/OpenMP/simd_private_taskloop_codegen.cpp (+196-196)
  • (modified) clang/test/OpenMP/single_codegen.cpp (+662-662)
  • (modified) clang/test/OpenMP/single_firstprivate_codegen.cpp (+32-32)
  • (modified) clang/test/OpenMP/single_private_codegen.cpp (+13-13)
  • (modified) clang/test/OpenMP/target_codegen.cpp (+10-10)
  • (modified) clang/test/OpenMP/target_data_map_codegen_hold.cpp (+44-44)
  • (modified) clang/test/OpenMP/target_data_no_device_codegen.cpp (+2-2)
  • (modified) clang/test/OpenMP/target_data_use_device_addr_codegen.cpp (+8-8)
  • (modified) clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp (+5-5)
  • (modified) clang/test/OpenMP/target_data_use_device_ptr_inheritance_codegen.cpp (+14-14)
  • (modified) clang/test/OpenMP/target_defaultmap_codegen_01.cpp (+8-8)
  • (modified) clang/test/OpenMP/target_defaultmap_codegen_02.cpp (+1-1)
  • (modified) clang/test/OpenMP/target_depend_codegen.cpp (+14-14)
diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h
index 5d59d5a4ae2c1..66bd2e4d36d3f 100644
--- a/clang/lib/CodeGen/CGBuilder.h
+++ b/clang/lib/CodeGen/CGBuilder.h
@@ -210,10 +210,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
   /// Given
   ///   %addr = {T1, T2...}* ...
   /// produce
-  ///   %name = getelementptr inbounds %addr, i32 0, i32 index
+  ///   %name = getelementptr inbounds nuw %addr, i32 0, i32 index
   ///
   /// This API assumes that drilling into a struct like this is always an
-  /// inbounds operation.
+  /// inbounds and nuw operation.
   using CGBuilderBaseTy::CreateStructGEP;
   Address CreateStructGEP(Address Addr, unsigned Index,
                           const llvm::Twine &Name = "") {
@@ -222,7 +222,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
     const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
     auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
 
-    return Address(CreateStructGEP(Addr.getElementType(), Addr.getBasePointer(),
+    return Address(CreateNUWStructGEP(Addr.getElementType(), Addr.getBasePointer(),
                                    Index, Name),
                    ElTy->getElementType(Index),
                    Addr.getAlignment().alignmentAtOffset(Offset),
diff --git a/clang/test/C/C2y/n3254.c b/clang/test/C/C2y/n3254.c
index 60d068cf9980b..e114735a9cb79 100644
--- a/clang/test/C/C2y/n3254.c
+++ b/clang/test/C/C2y/n3254.c
@@ -27,7 +27,7 @@ struct S {
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
 // CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[S_PTR]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 8
-// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 0
+// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 0
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[X]], align 4
 // CHECK-NEXT:    ret i32 [[TMP1]]
 //
@@ -42,10 +42,10 @@ int foo() {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 4
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 1
+// CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 1
 // CHECK-NEXT:    store i8 97, ptr [[C]], align 4
 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[C2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 1
+// CHECK-NEXT:    [[C2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 1
 // CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[C2]], align 4
 // CHECK-NEXT:    ret i8 [[TMP0]]
 //
@@ -60,10 +60,10 @@ char bar() {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 4
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 2
+// CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 2
 // CHECK-NEXT:    store float 3.000000e+00, ptr [[F]], align 4
 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 2
+// CHECK-NEXT:    [[F2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 2
 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[F2]], align 4
 // CHECK-NEXT:    ret float [[TMP0]]
 //
@@ -83,11 +83,11 @@ struct T {
 // CHECK-NEXT:    [[T:%.*]] = alloca [[STRUCT_T:%.*]], align 4
 // CHECK-NEXT:    [[S_PTR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[T]], i8 0, i64 12, i1 false)
-// CHECK-NEXT:    [[BUFFER:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[T]], i32 0, i32 0
+// CHECK-NEXT:    [[BUFFER:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[T]], i32 0, i32 0
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
 // CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[S_PTR]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 8
-// CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 1
+// CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 1
 // CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[C]], align 4
 // CHECK-NEXT:    ret i8 [[TMP1]]
 //
@@ -107,11 +107,11 @@ char quux() {
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
 // CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[T_PTR]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[T_PTR]], align 8
-// CHECK-NEXT:    [[BUFFER1:%.*]] = getelementptr inbounds [[STRUCT_T:%.*]], ptr [[TMP0]], i32 0, i32 0
+// CHECK-NEXT:    [[BUFFER1:%.*]] = getelementptr inbounds nuw [[STRUCT_T:%.*]], ptr [[TMP0]], i32 0, i32 0
 // CHECK-NEXT:    [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER1]], i64 0, i64 0
 // CHECK-NEXT:    store ptr [[ARRAYDECAY2]], ptr [[S_PTR]], align 8
 // CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[S_PTR]], align 8
-// CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[TMP1]], i32 0, i32 2
+// CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP1]], i32 0, i32 2
 // CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[F]], align 4
 // CHECK-NEXT:    ret float [[TMP2]]
 //
@@ -128,16 +128,16 @@ float quibble() {
 // CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 4
 // CHECK-NEXT:    [[S_PTR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[BUFFER1:%.*]] = getelementptr inbounds [[STRUCT_T:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 0
+// CHECK-NEXT:    [[BUFFER1:%.*]] = getelementptr inbounds nuw [[STRUCT_T:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 0
 // CHECK-NEXT:    [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER1]], i64 0, i64 0
-// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[ARRAYDECAY2]], i32 0, i32 0
+// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY2]], i32 0, i32 0
 // CHECK-NEXT:    store i32 12, ptr [[X]], align 4
 // CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0
-// CHECK-NEXT:    [[BUFFER4:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[ARRAYDECAY3]], i32 0, i32 0
+// CHECK-NEXT:    [[BUFFER4:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[ARRAYDECAY3]], i32 0, i32 0
 // CHECK-NEXT:    [[ARRAYDECAY5:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER4]], i64 0, i64 0
 // CHECK-NEXT:    store ptr [[ARRAYDECAY5]], ptr [[S_PTR]], align 8
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 8
-// CHECK-NEXT:    [[X6:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[TMP0]], i32 0, i32 0
+// CHECK-NEXT:    [[X6:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[TMP0]], i32 0, i32 0
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[X6]], align 4
 // CHECK-NEXT:    ret i32 [[TMP1]]
 //
diff --git a/clang/test/C/C2y/n3259.c b/clang/test/C/C2y/n3259.c
index 42c6720b2a665..2e94e3fc971df 100644
--- a/clang/test/C/C2y/n3259.c
+++ b/clang/test/C/C2y/n3259.c
@@ -12,52 +12,52 @@ void test() {
   // CHECK: store float 0
   _Complex float f = __builtin_complex(1.0f, 0.0f);
 
-  // CHECK:      %[[F_REALP1:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK:      %[[F_REALP1:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
   // CHECK-NEXT: %[[F_REAL:.+]] = load float, ptr %[[F_REALP1]]
-  // CHECK-NEXT: %[[F_IMAGP2:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_IMAGP2:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: %[[F_IMAG:.+]] = load float, ptr %[[F_IMAGP2]]
   // CHECK-NEXT: %[[INC:.+]] = fadd float %[[F_REAL]], 1.000000e+00
-  // CHECK-NEXT: %[[F_REALP3:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
-  // CHECK-NEXT: %[[F_IMAGP4:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_REALP3:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK-NEXT: %[[F_IMAGP4:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: store float %[[INC]], ptr %[[F_REALP3]]
   // CHECK-NEXT: store float %[[F_IMAG]], ptr %[[F_IMAGP4]]
   f++; /* expected-warning {{'++' on an object of complex type is a C2y extension}}
           pre-c2y-warning {{'++' on an object of complex type is incompatible with C standards before C2y}}
         */
 
-  // CHECK:      %[[F_REALP5:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK:      %[[F_REALP5:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
   // CHECK-NEXT: %[[F_REAL6:.+]] = load float, ptr %[[F_REALP5]]
-  // CHECK-NEXT: %[[F_IMAGP7:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_IMAGP7:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: %[[F_IMAG8:.+]] = load float, ptr %[[F_IMAGP7]]
   // CHECK-NEXT: %[[INC9:.+]] = fadd float %[[F_REAL6]], 1.000000e+00
-  // CHECK-NEXT: %[[F_REALP10:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
-  // CHECK-NEXT: %[[F_IMAGP11:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_REALP10:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK-NEXT: %[[F_IMAGP11:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: store float %[[INC9]], ptr %[[F_REALP10]]
   // CHECK-NEXT: store float %[[F_IMAG8]], ptr %[[F_IMAGP11]]
   ++f; /* expected-warning {{'++' on an object of complex type is a C2y extension}}
           pre-c2y-warning {{'++' on an object of complex type is incompatible with C standards before C2y}}
         */
 
-  // CHECK:      %[[F_REALP12:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK:      %[[F_REALP12:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
   // CHECK-NEXT: %[[F_REAL13:.+]] = load float, ptr %[[F_REALP12]]
-  // CHECK-NEXT: %[[F_IMAGP14:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_IMAGP14:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: %[[F_IMAG15:.+]] = load float, ptr %[[F_IMAGP14]]
   // CHECK-NEXT: %[[DEC:.+]] = fadd float %[[F_REAL13]], -1.000000e+00
-  // CHECK-NEXT: %[[F_REALP16:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
-  // CHECK-NEXT: %[[F_IMAGP17:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_REALP16:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK-NEXT: %[[F_IMAGP17:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: store float %[[DEC]], ptr %[[F_REALP16]]
   // CHECK-NEXT: store float %[[F_IMAG15]], ptr %[[F_IMAGP17]]
   f--; /* expected-warning {{'--' on an object of complex type is a C2y extension}}
           pre-c2y-warning {{'--' on an object of complex type is incompatible with C standards before C2y}}
         */
 
-  // CHECK:      %[[F_REALP18:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK:      %[[F_REALP18:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
   // CHECK-NEXT: %[[F_REAL19:.+]] = load float, ptr %[[F_REALP18]]
-  // CHECK-NEXT: %[[F_IMAGP20:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_IMAGP20:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: %[[F_IMAG21:.+]] = load float, ptr %[[F_IMAGP20]]
   // CHECK-NEXT: %[[DEC22:.+]] = fadd float %[[F_REAL19]], -1.000000e+00
-  // CHECK-NEXT: %[[F_REALP23:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 0
-  // CHECK-NEXT: %[[F_IMAGP24:.+]] = getelementptr inbounds { float, float }, ptr %[[F]], i32 0, i32 1
+  // CHECK-NEXT: %[[F_REALP23:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 0
+  // CHECK-NEXT: %[[F_IMAGP24:.+]] = getelementptr inbounds nuw { float, float }, ptr %[[F]], i32 0, i32 1
   // CHECK-NEXT: store float %[[DEC22]], ptr %[[F_REALP23]]
   // CHECK-NEXT: store float %[[F_IMAG21]], ptr %[[F_IMAGP24]]
   --f; /* expected-warning {{'--' on an object of complex type is a C2y extension}}
diff --git a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
index 82b5ac0fdc06c..8911257741c33 100644
--- a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
+++ b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c
@@ -10,8 +10,8 @@ _Complex float foo1(_Complex float x) {
 // CHECK:                   ret { float, float }
 
 // PPC32LNX-LABEL:          define{{.*}} void @foo1(ptr dead_on_unwind noalias writable sret({ float, float }) align 4 %agg.result, ptr noundef byval({ float, float }) align 4 %x) #0 {
-// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds { float, float }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds { float, float }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds nuw { float, float }, ptr %agg.result, i32 0, i32 1
 // PPC32LNX-NEXT:           store float %{{.*}}, ptr [[RETREAL]], align 4
 // PPC32LNX-NEXT:           store float %{{.*}}, ptr [[RETIMAG]], align 4
 }
@@ -22,8 +22,8 @@ _Complex double foo2(_Complex double x) {
 // CHECK:                   ret { double, double }
 
 // PPC32LNX-LABEL:          define{{.*}} void @foo2(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result, ptr noundef byval({ double, double }) align 8 %x) #0 {
-// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds { double, double }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds { double, double }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds nuw { double, double }, ptr %agg.result, i32 0, i32 1
 // PPC32LNX-NEXT:           store double %{{.*}}, ptr [[RETREAL]], align 8
 // PPC32LNX-NEXT:           store double %{{.*}}, ptr [[RETIMAG]], align 8
 }
@@ -37,8 +37,8 @@ _Complex long double foo3(_Complex long double x) {
 // CHECK-LDBL128:           ret { ppc_fp128, ppc_fp128 }
 
 // PPC32LNX-LABEL:          define{{.*}} void @foo3(ptr dead_on_unwind noalias writable sret({ ppc_fp128, ppc_fp128 }) align 16 %agg.result, ptr noundef byval({ ppc_fp128, ppc_fp128 }) align 16 %x) #0 {
-// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 0
-// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 1
+// PPC32LNX:                [[RETREAL:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 0
+// PPC32LNX-NEXT:           [[RETIMAG:%.*]] = getelementptr inbounds nuw { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 1
 // PPC32LNX-NEXT:           store ppc_fp128 %{{.*}}, ptr [[RETREAL]], align 16
 // PPC32LNX-NEXT:           store ppc_fp128 %{{.*}}, ptr [[RETIMAG]], align 16
 }
diff --git a/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c b/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c
index 2f5459d1bb9c4..08d3d2a9cc3c3 100644
--- a/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c
+++ b/clang/test/CodeGen/PowerPC/ppc64le-varargs-f128.c
@@ -93,7 +93,7 @@ void long_double(int n, ...) {
 // IEEE: %[[V0:[0-9a-zA-Z_.]+]] = getelementptr inbounds i8, ptr %[[ALIGN]], i64 16
 // IEEE: store ptr %[[V0]], ptr %[[AP]], align 8
 // IEEE: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %[[TMP:[0-9a-zA-Z_.]+]], ptr align 16 %[[ALIGN]], i64 16, i1 false)
-// IEEE: %[[COERCE:[0-9a-zA-Z_.]+]] = getelementptr inbounds %struct.ldbl128_s, ptr %[[TMP]], i32 0, i32 0
+// IEEE: %[[COERCE:[0-9a-zA-Z_.]+]] = getelementptr inbounds nuw %struct.ldbl128_s, ptr %[[TMP]], i32 0, i32 0
 // IEEE: %[[V4:[0-9a-zA-Z_.]+]] = load fp128, ptr %[[COERCE]], align 16
 // IEEE: call void @foo_ls(fp128 inreg %[[V4]])
 // IEEE: call void @llvm.va_end.p0(ptr %[[AP]])
diff --git a/clang/test/CodeGen/RISCV/bfloat-abi.c b/clang/test/CodeGen/RISCV/bfloat-abi.c
index f38646c8b12ff..f7c82adaa6d89 100644
--- a/clang/test/CodeGen/RISCV/bfloat-abi.c
+++ b/clang/test/CodeGen/RISCV/bfloat-abi.c
@@ -14,9 +14,9 @@ struct bfloat1 {
 // CHECK-RV64-NEXT:    [[COERCE_DIVE_COERCE:%.*]] = alloca i64, align 8
 // CHECK-RV64-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2
 // CHECK-RV64-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2
-// CHECK-RV64-NEXT:    [[A1:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
+// CHECK-RV64-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
 // CHECK-RV64-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 2
-// CHECK-RV64-NEXT:    [[COERCE_DIVE:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
+// CHECK-RV64-NEXT:    [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
 // CHECK-RV64-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[COERCE_DIVE_COERCE]], ptr align 2 [[COERCE_DIVE]], i64 2, i1 false)
 // CHECK-RV64-NEXT:    [[TMP1:%.*]] = load i64, ptr [[COERCE_DIVE_COERCE]], align 8
 // CHECK-RV64-NEXT:    ret i64 [[TMP1]]
@@ -29,9 +29,9 @@ struct bfloat1 {
 // CHECK-RV32-NEXT:    [[COERCE_DIVE_COERCE:%.*]] = alloca i32, align 4
 // CHECK-RV32-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2
 // CHECK-RV32-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2
-// CHECK-RV32-NEXT:    [[A1:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
+// CHECK-RV32-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
 // CHECK-RV32-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 2
-// CHECK-RV32-NEXT:    [[COERCE_DIVE:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
+// CHECK-RV32-NEXT:    [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT1]], ptr [[RETVAL]], i32 0, i32 0
 // CHECK-RV32-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[COERCE_DIVE_COERCE]], ptr align 2 [[COERCE_DIVE]], i32 2, i1 false)
 // CHECK-RV32-NEXT:    [[TMP1:%.*]] = load i32, ptr [[COERCE_DIVE_COERCE]], align 4
 // CHECK-RV32-NEXT:    ret i32 [[TMP1]]
@@ -57,10 +57,10 @@ struct bfloat2 {
 // CHECK-RV64-NEXT:    store bfloat [[A]], ptr [[A_ADDR]], align 2
 // CHECK-RV64-NEXT:    store bfloat [[B]], ptr [[B_ADDR]], align 2
 // CHECK-RV64-NEXT:    [[TMP0:%.*]] = load bfloat, ptr [[A_ADDR]], align 2
-// CHECK-RV64-NEXT:    [[A1:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT2]], ptr [[RETVAL]], i32 0, i32 0
+// CHECK-RV64-NEXT:    [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_BFLOAT2]], ptr [[RETVAL]], i32 0, i32 0
 // CHECK-RV64-NEXT:    store bfloat [[TMP0]], ptr [[A1]], align 2
 // CHECK-RV64-NEXT:    [[TMP1:%.*]] = load bfloat, ptr [[B_ADDR]], align 2
-// CHECK-RV64-NEXT:    [[B2:%.*]] = getelementptr inbounds [[STRUCT_BFLOAT2]], ptr [[RETVAL]], i32 0, i32 1
+// CHECK-RV64-NEXT:    [[B2...
[truncated]

Copy link

github-actions bot commented Jul 18, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@hazzlim
Copy link
Contributor Author

hazzlim commented Jul 18, 2024

This seemed like the right place to make the change - please let me know if not!

I've not restricted this to a subset of languages because it seems fairly unambiguous that nuw holds for these inbounds struct member accesses, but it could be limited to e.g. C/C++ if that is more appropriate.

@hazzlim hazzlim force-pushed the clang-nuw-struct branch 2 times, most recently from bde0a64 to 0daf16a Compare July 18, 2024 18:18
@nikic nikic requested review from rjmccall and efriedma-quic July 25, 2024 14:39
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fine to me. Worth noting though that these nuw flags could also be inferred (inbounds + non-negative offset is nuw), so annotating this in the frontend is not strictly necessary.

@rjmccall
Copy link
Contributor

CGBuilder is just aiming to provide an Address overload of LLVM's CreateStructGEP. It seems wrong for two overloads to have subtly different behavior.

Is there a reason why LLVM's CreateStructGEP doesn't add nuw itself?

@hazzlim
Copy link
Contributor Author

hazzlim commented Jul 25, 2024

CGBuilder is just aiming to provide an Address overload of LLVM's CreateStructGEP. It seems wrong for two overloads to have subtly different behavior.

Is there a reason why LLVM's CreateStructGEP doesn't add nuw itself?

Good point - I can see that it makes more sense to add the flag there.

I can rework this patch to do this. Before doing so - do people think it still makes sense to do add the flag in ‘llvm::CreateStructGEP’, given that as @nikic points out we can infer the flag at the IR level?

@hazzlim
Copy link
Contributor Author

hazzlim commented Jul 30, 2024

CGBuilder is just aiming to provide an Address overload of LLVM's CreateStructGEP. It seems wrong for two overloads to have subtly different behavior.
Is there a reason why LLVM's CreateStructGEP doesn't add nuw itself?

Good point - I can see that it makes more sense to add the flag there.

I can rework this patch to do this. Before doing so - do people think it still makes sense to do add the flag in ‘llvm::CreateStructGEP’, given that as @nikic points out we can infer the flag at the IR level?

@rjmccall I've reworked this patch so that the nuw flag is added in LLVM's CreateStructGEP directly.

@rjmccall
Copy link
Contributor

Well, that's a heroic amount of test updates.

I have no problem with the clang changes here. I'm happy to leave it up to middle-end folks whether adding this attribute is worthwhile given that it can be trivially derived from inbounds.

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you already put in the test update work, I'm happy to take it :)

Value *Idxs[] = {
ConstantInt::get(Type::getInt32Ty(Context), Idx0),
ConstantInt::get(Type::getInt32Ty(Context), Idx1)
};

if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, GEPNoWrapFlags::none()))
if (auto *V =
Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/NWFlags.isInBounds()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be?

Suggested change
Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/NWFlags.isInBounds()))
Folder.FoldGEP(Ty, Ptr, Idxs, NWFlags))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes good point - thanks for spotting!

I've updated with this change, as well as a couple of arch specific test updates that were missed before due to my build config.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this one still passes NWFlags.isInBounds() instead of the full NWFlags?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sorry about that - updated to pass the full NWFlags correctly (+ associated test updates).

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM once CI is happy. It looks like there are some mlir test failures.

hazzlim added 4 commits August 9, 2024 09:00
Generate nuw GEPs for struct member accesses, as inbounds + non-negative
implies nuw.

Regression tests are updated using update scripts where possible, and by
find + replace where not.
@hazzlim hazzlim merged commit 94473f4 into llvm:main Aug 9, 2024
8 checks passed
kutemeikito added a commit to kutemeikito/llvm-project that referenced this pull request Aug 10, 2024
* 'main' of https://github.com/llvm/llvm-project: (700 commits)
  [SandboxIR][NFC] SingleLLVMInstructionImpl class (llvm#102687)
  [ThinLTO]Clean up 'import-assume-unique-local' flag. (llvm#102424)
  [nsan] Make #include more conventional
  [SandboxIR][NFC] Use Tracker.emplaceIfTracking()
  [libc]  Moved range_reduction_double ifdef statement (llvm#102659)
  [libc] Fix CFP long double and add tests (llvm#102660)
  [TargetLowering] Handle vector types in expandFixedPointMul (llvm#102635)
  [compiler-rt][NFC] Replace environment variable with %t (llvm#102197)
  [UnitTests] Convert a test to use opaque pointers (llvm#102668)
  [CodeGen][NFCI] Don't re-implement parts of ASTContext::getIntWidth (llvm#101765)
  [SandboxIR] Clean up tracking code with the help of emplaceIfTracking() (llvm#102406)
  [mlir][bazel] remove extra blanks in mlir-tblgen test
  [NVPTX][NFC] Update tests to use bfloat type (llvm#101493)
  [mlir] Add support for parsing nested PassPipelineOptions (llvm#101118)
  [mlir][bazel] add missing td dependency in mlir-tblgen test
  [flang][cuda] Fix lib dependency
  [libc] Clean up remaining use of *_WIDTH macros in printf (llvm#102679)
  [flang][cuda] Convert cuf.alloc for box to fir.alloca in device context (llvm#102662)
  [SandboxIR] Implement the InsertElementInst class (llvm#102404)
  [libc] Fix use of cpp::numeric_limits<...>::digits (llvm#102674)
  [mlir][ODS] Verify type constraints in Types and Attributes (llvm#102326)
  [LTO] enable `ObjCARCContractPass` only on optimized build  (llvm#101114)
  [mlir][ODS] Consistent `cppType` / `cppClassName` usage (llvm#102657)
  [lldb] Move definition of SBSaveCoreOptions dtor out of header (llvm#102539)
  [libc] Use cpp::numeric_limits in preference to C23 <limits.h> macros (llvm#102665)
  [clang] Implement -fptrauth-auth-traps. (llvm#102417)
  [LLVM][rtsan] rtsan transform to preserve CFGAnalyses (llvm#102651)
  Revert "[AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (llvm#102086)"
  [RISCV][GISel] Add missing tests for G_CTLZ/CTTZ instruction selection. NFC
  Return available function types for BindingDecls. (llvm#102196)
  [clang] Wire -fptrauth-returns to "ptrauth-returns" fn attribute. (llvm#102416)
  [RISCV] Remove riscv-experimental-rv64-legal-i32. (llvm#102509)
  [RISCV] Move PseudoVSET(I)VLI expansion to use PseudoInstExpansion. (llvm#102496)
  [NVPTX] support switch statement with brx.idx (reland) (llvm#102550)
  [libc][newhdrgen]sorted function names in yaml (llvm#102544)
  [GlobalIsel] Combine G_ADD and G_SUB with constants (llvm#97771)
  Suppress spurious warnings due to R_RISCV_SET_ULEB128
  [scudo] Separated committed and decommitted entries. (llvm#101409)
  [MIPS] Fix missing ANDI optimization (llvm#97689)
  [Clang] Add env var for nvptx-arch/amdgpu-arch timeout (llvm#102521)
  [asan] Switch allocator to dynamic base address (llvm#98511)
  [AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (llvm#102086)
  [libc][math][c23] Add fadd{l,f128} C23 math functions (llvm#102531)
  [mlir][bazel] revert bazel rule change for DLTITransformOps
  [msan] Support vst{2,3,4}_lane instructions (llvm#101215)
  Revert "[MLIR][DLTI][Transform] Introduce transform.dlti.query (llvm#101561)"
  [X86] pr57673.ll - generate MIR test checks
  [mlir][vector][test] Split tests from vector-transfer-flatten.mlir (llvm#102584)
  [mlir][bazel] add bazel rule for DLTITransformOps
  OpenMPOpt: Remove dead include
  [IR] Add method to GlobalVariable to change type of initializer. (llvm#102553)
  [flang][cuda] Force default allocator in device code (llvm#102238)
  [llvm] Construct SmallVector<SDValue> with ArrayRef (NFC) (llvm#102578)
  [MLIR][DLTI][Transform] Introduce transform.dlti.query (llvm#101561)
  [AMDGPU][AsmParser][NFC] Remove a misleading comment. (llvm#102604)
  [Arm][AArch64][Clang] Respect function's branch protection attributes. (llvm#101978)
  [mlir] Verifier: steal bit to track seen instead of set. (llvm#102626)
  [Clang] Fix Handling of Init Capture with Parameter Packs in LambdaScopeForCallOperatorInstantiationRAII (llvm#100766)
  [X86] Convert truncsat clamping patterns to use SDPatternMatch. NFC.
  [gn] Give two scripts argparse.RawDescriptionHelpFormatter
  [bazel] Add missing dep for the SPIRVToLLVM target
  [Clang] Simplify specifying passes via -Xoffload-linker (llvm#102483)
  [bazel] Port for d45de80
  [SelectionDAG] Use unaligned store/load to move AVX registers onto stack for `insertelement` (llvm#82130)
  [Clang][OMPX] Add the code generation for multi-dim `num_teams` (llvm#101407)
  [ARM] Regenerate big-endian-vmov.ll. NFC
  [AMDGPU][AsmParser][NFCI] All NamedIntOperands to be of the i32 type. (llvm#102616)
  [libc][math][c23] Add totalorderl function. (llvm#102564)
  [mlir][spirv] Support `memref` in `convert-to-spirv` pass (llvm#102534)
  [MLIR][GPU-LLVM] Convert `gpu.func` to `llvm.func` (llvm#101664)
  Fix a unit test input file (llvm#102567)
  [llvm-readobj][COFF] Dump hybrid objects for ARM64X files. (llvm#102245)
  AMDGPU/NewPM: Port SIFixSGPRCopies to new pass manager (llvm#102614)
  [MemoryBuiltins] Simplify getCalledFunction() helper (NFC)
  [AArch64] Add invalid 1 x vscale costs for reductions and reduction-operations. (llvm#102105)
  [MemoryBuiltins] Handle allocator attributes on call-site
  LSV/test/AArch64: add missing lit.local.cfg; fix build (llvm#102607)
  Revert "Enable logf128 constant folding for hosts with 128bit floats (llvm#96287)"
  [RISCV] Add Syntacore SCR5 RV32/64 processors definition (llvm#102285)
  [InstCombine] Remove unnecessary RUN line from test (NFC)
  [flang][OpenMP] Handle multiple ranges in `num_teams` clause (llvm#102535)
  [mlir][vector] Add tests for scalable vectors in one-shot-bufferize.mlir (llvm#102361)
  [mlir][vector] Disable `vector.matrix_multiply` for scalable vectors (llvm#102573)
  [clang] Implement CWG2627 Bit-fields and narrowing conversions (llvm#78112)
  [NFC] Use references to avoid copying (llvm#99863)
  Revert "[mlir][ArmSME] Pattern to swap shape_cast(tranpose) with transpose(shape_cast) (llvm#100731)" (llvm#102457)
  [IRBuilder] Generate nuw GEPs for struct member accesses (llvm#99538)
  [bazel] Port for 9b06e25
  [CodeGen][NewPM] Improve start/stop pass error message CodeGenPassBuilder (llvm#102591)
  [AArch64] Implement TRBMPAM_EL1 system register (llvm#102485)
  [InstCombine] Fixing wrong select folding in vectors with undef elements (llvm#102244)
  [AArch64] Sink operands to fmuladd. (llvm#102297)
  LSV: document hang reported in llvm#37865 (llvm#102479)
  Enable logf128 constant folding for hosts with 128bit floats (llvm#96287)
  [RISCV][clang] Remove bfloat base type in non-zvfbfmin vcreate (llvm#102146)
  [RISCV][clang] Add missing `zvfbfmin` to `vget_v` intrinsic (llvm#102149)
  [mlir][vector] Add mask elimination transform (llvm#99314)
  [Clang][Interp] Fix display of syntactically-invalid note for member function calls (llvm#102170)
  [bazel] Port for 3fffa6d
  [DebugInfo][RemoveDIs] Use iterator-inserters in clang (llvm#102006)
  ...

Signed-off-by: Edwiin Kusuma Jaya <kutemeikito0905@gmail.com>
cachemeifyoucan added a commit to cachemeifyoucan/llvm-project that referenced this pull request Aug 12, 2024
Update tests with `getelementptr inbound nuw`

rdar://133702351
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AMDGPU backend:NVPTX backend:PowerPC backend:RISC-V backend:SystemZ backend:WebAssembly backend:X86 clang:codegen IR generation bugs: mangling, exceptions, etc. clang:openmp OpenMP related changes to Clang clang Clang issues not falling into any other category coroutines C++20 coroutines flang:openmp HLSL HLSL Language Support llvm:ir llvm:transforms mlir:llvm mlir
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants