[llvm] cffbfd0 - [NFC][SROA] Revisit test coverage in non-capturing-call.ll

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 10 02:38:31 PST 2021


Author: Roman Lebedev
Date: 2021-11-10T13:38:23+03:00
New Revision: cffbfd01e37b6b83205dc3f087175c20973b148b

URL: https://github.com/llvm/llvm-project/commit/cffbfd01e37b6b83205dc3f087175c20973b148b
DIFF: https://github.com/llvm/llvm-project/commit/cffbfd01e37b6b83205dc3f087175c20973b148b.diff

LOG: [NFC][SROA] Revisit test coverage in non-capturing-call.ll

Added: 
    

Modified: 
    llvm/test/Transforms/SROA/non-capturing-call.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/SROA/non-capturing-call.ll b/llvm/test/Transforms/SROA/non-capturing-call.ll
index f6421f6def20d..da37df80ca865 100644
--- a/llvm/test/Transforms/SROA/non-capturing-call.ll
+++ b/llvm/test/Transforms/SROA/non-capturing-call.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -sroa -S | FileCheck %s
-; RUN: opt < %s -passes=sroa -S | FileCheck %s
+; RUN: opt < %s -passes=sroa -S | FileCheck %s --check-prefix=CHECK
+; RUN: opt < %s -passes=sroa -opaque-pointers -S | FileCheck %s --check-prefix=CHECK-OPAQUE
 
 define i32 @alloca_used_in_call(i32* nocapture nonnull readonly %data, i64 %n) {
 ; CHECK-LABEL: @alloca_used_in_call(
@@ -19,9 +19,29 @@ define i32 @alloca_used_in_call(i32* nocapture nonnull readonly %data, i64 %n) {
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @user_of_alloca(i32* nocapture nonnull [[RETVAL]])
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[RETVAL]], align 4
-; CHECK-NEXT:    ret i32 [[TMP1]]
+; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca(i32* nocapture nonnull [[RETVAL]])
+; CHECK-NEXT:    [[I1:%.*]] = load i32, i32* [[RETVAL]], align 4
+; CHECK-NEXT:    ret i32 [[I1]]
+;
+; CHECK-OPAQUE-LABEL: @alloca_used_in_call(
+; CHECK-OPAQUE-NEXT:  entry:
+; CHECK-OPAQUE-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    br label [[LOOP:%.*]]
+; CHECK-OPAQUE:       loop:
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-OPAQUE-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-OPAQUE-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-OPAQUE-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-OPAQUE-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-OPAQUE-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-OPAQUE:       exit:
+; CHECK-OPAQUE-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca(ptr nocapture nonnull [[RETVAL]])
+; CHECK-OPAQUE-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    ret i32 [[I1]]
 ;
 entry:
   %retval = alloca i32, align 4
@@ -40,9 +60,9 @@ loop:
   br i1 %exitcond, label %loop, label %exit
 
 exit:
-  %0 = call i32 @user_of_alloca(i32* nocapture nonnull %retval)
-  %1 = load i32, i32* %retval, align 4
-  ret i32 %1
+  %i0 = call i32 @user_of_alloca(i32* nocapture nonnull %retval)
+  %i1 = load i32, i32* %retval, align 4
+  ret i32 %i1
 }
 
 define i32 @alloca_captured_in_call(i32* nocapture nonnull readonly %data, i64 %n) {
@@ -62,9 +82,29 @@ define i32 @alloca_captured_in_call(i32* nocapture nonnull readonly %data, i64 %
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @capture_of_alloca(i32* nonnull [[RETVAL]])
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[RETVAL]], align 4
-; CHECK-NEXT:    ret i32 [[TMP1]]
+; CHECK-NEXT:    [[I0:%.*]] = call i32 @capture_of_alloca(i32* nonnull [[RETVAL]])
+; CHECK-NEXT:    [[I1:%.*]] = load i32, i32* [[RETVAL]], align 4
+; CHECK-NEXT:    ret i32 [[I1]]
+;
+; CHECK-OPAQUE-LABEL: @alloca_captured_in_call(
+; CHECK-OPAQUE-NEXT:  entry:
+; CHECK-OPAQUE-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    br label [[LOOP:%.*]]
+; CHECK-OPAQUE:       loop:
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-OPAQUE-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-OPAQUE-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-OPAQUE-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-OPAQUE-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-OPAQUE-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-OPAQUE:       exit:
+; CHECK-OPAQUE-NEXT:    [[I0:%.*]] = call i32 @capture_of_alloca(ptr nonnull [[RETVAL]])
+; CHECK-OPAQUE-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    ret i32 [[I1]]
 ;
 entry:
   %retval = alloca i32, align 4
@@ -83,9 +123,9 @@ loop:
   br i1 %exitcond, label %loop, label %exit
 
 exit:
-  %0 = call i32 @capture_of_alloca(i32* nonnull %retval)
-  %1 = load i32, i32* %retval, align 4
-  ret i32 %1
+  %i0 = call i32 @capture_of_alloca(i32* nonnull %retval)
+  %i1 = load i32, i32* %retval, align 4
+  ret i32 %i1
 }
 
 define i32 @alloca_with_gep_used_in_call(i32* nocapture nonnull readonly %data, i64 %n) {
@@ -106,9 +146,30 @@ define i32 @alloca_with_gep_used_in_call(i32* nocapture nonnull readonly %data,
 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, i32* [[RETVAL]], i32 0
-; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @user_of_alloca(i32* nocapture nonnull [[GEP]])
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[RETVAL]], align 4
-; CHECK-NEXT:    ret i32 [[TMP1]]
+; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca(i32* nocapture nonnull [[GEP]])
+; CHECK-NEXT:    [[I1:%.*]] = load i32, i32* [[RETVAL]], align 4
+; CHECK-NEXT:    ret i32 [[I1]]
+;
+; CHECK-OPAQUE-LABEL: @alloca_with_gep_used_in_call(
+; CHECK-OPAQUE-NEXT:  entry:
+; CHECK-OPAQUE-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    br label [[LOOP:%.*]]
+; CHECK-OPAQUE:       loop:
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-OPAQUE-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-OPAQUE-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-OPAQUE-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-OPAQUE-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-OPAQUE-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-OPAQUE:       exit:
+; CHECK-OPAQUE-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[RETVAL]], i32 0
+; CHECK-OPAQUE-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca(ptr nocapture nonnull [[GEP]])
+; CHECK-OPAQUE-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    ret i32 [[I1]]
 ;
 entry:
   %retval = alloca i32, align 4
@@ -128,9 +189,9 @@ loop:
 
 exit:
   %gep = getelementptr i32, i32* %retval, i32 0
-  %0 = call i32 @user_of_alloca(i32* nocapture nonnull %gep)
-  %1 = load i32, i32* %retval, align 4
-  ret i32 %1
+  %i0 = call i32 @user_of_alloca(i32* nocapture nonnull %gep)
+  %i1 = load i32, i32* %retval, align 4
+  ret i32 %i1
 }
 
 define i32 @alloca_captured_second_arg(i32* nocapture nonnull readonly %data, i64 %n) {
@@ -150,9 +211,29 @@ define i32 @alloca_captured_second_arg(i32* nocapture nonnull readonly %data, i6
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @capture_with_multiple_args(i32* nocapture nonnull [[RETVAL]], i32* nonnull [[RETVAL]])
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[RETVAL]], align 4
-; CHECK-NEXT:    ret i32 [[TMP1]]
+; CHECK-NEXT:    [[I0:%.*]] = call i32 @capture_with_multiple_args(i32* nocapture nonnull [[RETVAL]], i32* nonnull [[RETVAL]])
+; CHECK-NEXT:    [[I1:%.*]] = load i32, i32* [[RETVAL]], align 4
+; CHECK-NEXT:    ret i32 [[I1]]
+;
+; CHECK-OPAQUE-LABEL: @alloca_captured_second_arg(
+; CHECK-OPAQUE-NEXT:  entry:
+; CHECK-OPAQUE-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    br label [[LOOP:%.*]]
+; CHECK-OPAQUE:       loop:
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-OPAQUE-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-OPAQUE-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-OPAQUE-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-OPAQUE-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-OPAQUE-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-OPAQUE:       exit:
+; CHECK-OPAQUE-NEXT:    [[I0:%.*]] = call i32 @capture_with_multiple_args(ptr nocapture nonnull [[RETVAL]], ptr nonnull [[RETVAL]])
+; CHECK-OPAQUE-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    ret i32 [[I1]]
 ;
 entry:
   %retval = alloca i32, align 4
@@ -171,9 +252,9 @@ loop:
   br i1 %exitcond, label %loop, label %exit
 
 exit:
-  %0 = call i32 @capture_with_multiple_args(i32* nocapture nonnull %retval, i32* nonnull %retval)
-  %1 = load i32, i32* %retval, align 4
-  ret i32 %1
+  %i0 = call i32 @capture_with_multiple_args(i32* nocapture nonnull %retval, i32* nonnull %retval)
+  %i1 = load i32, i32* %retval, align 4
+  ret i32 %i1
 }
 
 define i32 @alloca_used_in_maybe_throwing_call(i32* nocapture nonnull readonly %data, i64 %n) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)  {
@@ -193,17 +274,45 @@ define i32 @alloca_used_in_maybe_throwing_call(i32* nocapture nonnull readonly %
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[TMP0:%.*]] = invoke i32 @user_of_alloca(i32* nocapture nonnull [[RETVAL]])
+; CHECK-NEXT:    [[I0:%.*]] = invoke i32 @user_of_alloca(i32* nocapture nonnull [[RETVAL]])
 ; CHECK-NEXT:    to label [[CONT:%.*]] unwind label [[UW:%.*]]
 ; CHECK:       cont:
 ; CHECK-NEXT:    br label [[END:%.*]]
 ; CHECK:       uw:
-; CHECK-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+; CHECK-NEXT:    [[I1:%.*]] = landingpad { i8*, i32 }
 ; CHECK-NEXT:    catch i8* null
 ; CHECK-NEXT:    br label [[END]]
 ; CHECK:       end:
-; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[RETVAL]], align 4
-; CHECK-NEXT:    ret i32 [[TMP2]]
+; CHECK-NEXT:    [[I2:%.*]] = load i32, i32* [[RETVAL]], align 4
+; CHECK-NEXT:    ret i32 [[I2]]
+;
+; CHECK-OPAQUE-LABEL: @alloca_used_in_maybe_throwing_call(
+; CHECK-OPAQUE-NEXT:  entry:
+; CHECK-OPAQUE-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    br label [[LOOP:%.*]]
+; CHECK-OPAQUE:       loop:
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-OPAQUE-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-OPAQUE-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-OPAQUE-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-OPAQUE-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-OPAQUE-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-OPAQUE:       exit:
+; CHECK-OPAQUE-NEXT:    [[I0:%.*]] = invoke i32 @user_of_alloca(ptr nocapture nonnull [[RETVAL]])
+; CHECK-OPAQUE-NEXT:    to label [[CONT:%.*]] unwind label [[UW:%.*]]
+; CHECK-OPAQUE:       cont:
+; CHECK-OPAQUE-NEXT:    br label [[END:%.*]]
+; CHECK-OPAQUE:       uw:
+; CHECK-OPAQUE-NEXT:    [[I1:%.*]] = landingpad { ptr, i32 }
+; CHECK-OPAQUE-NEXT:    catch ptr null
+; CHECK-OPAQUE-NEXT:    br label [[END]]
+; CHECK-OPAQUE:       end:
+; CHECK-OPAQUE-NEXT:    [[I2:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    ret i32 [[I2]]
 ;
 entry:
   %retval = alloca i32, align 4
@@ -222,18 +331,18 @@ loop:
   br i1 %exitcond, label %loop, label %exit
 
 exit:
-  %0 = invoke i32 @user_of_alloca(i32* nocapture nonnull %retval) to label %cont unwind label %uw
+  %i0 = invoke i32 @user_of_alloca(i32* nocapture nonnull %retval) to label %cont unwind label %uw
 
 cont:
   br label %end
 
 uw:
-  %1 = landingpad { i8*, i32 } catch i8* null
+  %i1 = landingpad { i8*, i32 } catch i8* null
   br label %end
 
 end:
-  %2 = load i32, i32* %retval, align 4
-  ret i32 %2
+  %i2 = load i32, i32* %retval, align 4
+  ret i32 %i2
 }
 
 define i32 @alloca_used_in_maybe_throwing_call_with_same_dests(i32* nocapture nonnull readonly %data, i64 %n) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)  {
@@ -253,15 +362,41 @@ define i32 @alloca_used_in_maybe_throwing_call_with_same_dests(i32* nocapture no
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[TMP0:%.*]] = invoke i32 @user_of_alloca(i32* nocapture nonnull [[RETVAL]])
+; CHECK-NEXT:    [[I0:%.*]] = invoke i32 @user_of_alloca(i32* nocapture nonnull [[RETVAL]])
 ; CHECK-NEXT:    to label [[END:%.*]] unwind label [[UW:%.*]]
 ; CHECK:       uw:
-; CHECK-NEXT:    [[TMP1:%.*]] = landingpad { i8*, i32 }
+; CHECK-NEXT:    [[I1:%.*]] = landingpad { i8*, i32 }
 ; CHECK-NEXT:    catch i8* null
 ; CHECK-NEXT:    br label [[END]]
 ; CHECK:       end:
-; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[RETVAL]], align 4
-; CHECK-NEXT:    ret i32 [[TMP2]]
+; CHECK-NEXT:    [[I2:%.*]] = load i32, i32* [[RETVAL]], align 4
+; CHECK-NEXT:    ret i32 [[I2]]
+;
+; CHECK-OPAQUE-LABEL: @alloca_used_in_maybe_throwing_call_with_same_dests(
+; CHECK-OPAQUE-NEXT:  entry:
+; CHECK-OPAQUE-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    br label [[LOOP:%.*]]
+; CHECK-OPAQUE:       loop:
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-OPAQUE-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-OPAQUE-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-OPAQUE-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-OPAQUE-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-OPAQUE-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-OPAQUE:       exit:
+; CHECK-OPAQUE-NEXT:    [[I0:%.*]] = invoke i32 @user_of_alloca(ptr nocapture nonnull [[RETVAL]])
+; CHECK-OPAQUE-NEXT:    to label [[END:%.*]] unwind label [[UW:%.*]]
+; CHECK-OPAQUE:       uw:
+; CHECK-OPAQUE-NEXT:    [[I1:%.*]] = landingpad { ptr, i32 }
+; CHECK-OPAQUE-NEXT:    catch ptr null
+; CHECK-OPAQUE-NEXT:    br label [[END]]
+; CHECK-OPAQUE:       end:
+; CHECK-OPAQUE-NEXT:    [[I2:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    ret i32 [[I2]]
 ;
 entry:
   %retval = alloca i32, align 4
@@ -280,15 +415,15 @@ loop:
   br i1 %exitcond, label %loop, label %exit
 
 exit:
-  %0 = invoke i32 @user_of_alloca(i32* nocapture nonnull %retval) to label %end unwind label %uw
+  %i0 = invoke i32 @user_of_alloca(i32* nocapture nonnull %retval) to label %end unwind label %uw
 
 uw:
-  %1 = landingpad { i8*, i32 } catch i8* null
+  %i1 = landingpad { i8*, i32 } catch i8* null
   br label %end
 
 end:
-  %2 = load i32, i32* %retval, align 4
-  ret i32 %2
+  %i2 = load i32, i32* %retval, align 4
+  ret i32 %i2
 }
 
 define [2 x i32] @part_of_alloca_used_in_call(i32* nocapture nonnull readonly %data, i64 %n) {
@@ -312,19 +447,310 @@ define [2 x i32] @part_of_alloca_used_in_call(i32* nocapture nonnull readonly %d
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @user_of_alloca(i32* nocapture nonnull [[RETVAL]])
-; CHECK-NEXT:    [[DOTFCA_0_GEP1:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0
-; CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load i32, i32* [[DOTFCA_0_GEP1]], align 4
-; CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [2 x i32] undef, i32 [[DOTFCA_0_LOAD]], 0
-; CHECK-NEXT:    [[DOTFCA_1_GEP2:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1
-; CHECK-NEXT:    [[DOTFCA_1_LOAD:%.*]] = load i32, i32* [[DOTFCA_1_GEP2]], align 4
-; CHECK-NEXT:    [[DOTFCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[DOTFCA_0_INSERT]], i32 [[DOTFCA_1_LOAD]], 1
-; CHECK-NEXT:    ret [2 x i32] [[DOTFCA_1_INSERT]]
+; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca(i32* nocapture nonnull [[RETVAL]])
+; CHECK-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, i32* [[I1_FCA_0_GEP]], align 4
+; CHECK-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] undef, i32 [[I1_FCA_0_LOAD]], 0
+; CHECK-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, i32* [[I1_FCA_1_GEP]], align 4
+; CHECK-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
+; CHECK-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
+;
+; CHECK-OPAQUE-LABEL: @part_of_alloca_used_in_call(
+; CHECK-OPAQUE-NEXT:  entry:
+; CHECK-OPAQUE-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
+; CHECK-OPAQUE-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[DOTFCA_0_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[DOTFCA_1_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1
+; CHECK-OPAQUE-NEXT:    br label [[LOOP:%.*]]
+; CHECK-OPAQUE:       loop:
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-OPAQUE-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-OPAQUE-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-OPAQUE-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-OPAQUE-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-OPAQUE-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-OPAQUE:       exit:
+; CHECK-OPAQUE-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca(ptr nocapture nonnull [[RETVAL]])
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] undef, i32 [[I1_FCA_0_LOAD]], 0
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
+; CHECK-OPAQUE-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
+;
+entry:
+  %retval.full = alloca [2 x i32], align 4
+  store [2 x i32] zeroinitializer, [2 x i32]* %retval.full, align 4
+  %retval = getelementptr inbounds [2 x i32], [2 x i32]* %retval.full, i64 0, i64 1
+  br label %loop
+
+loop:
+  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
+  %arrayidx = getelementptr inbounds i32, i32* %data, i64 %indvars.iv
+  %ld = load i32, i32* %arrayidx, align 4
+  %rdx = load i32, i32* %retval, align 4
+  %rdx.inc = add nsw i32 %rdx, %ld
+  store i32 %rdx.inc, i32* %retval, align 4
+  %indvars.iv.next = add nsw i64 %indvars.iv, 1
+  %exitcond = icmp ne i64 %indvars.iv.next, %n
+  br i1 %exitcond, label %loop, label %exit
+
+exit:
+  %i0 = call i32 @user_of_alloca(i32* nocapture nonnull %retval)
+  %i1 = load [2 x i32], [2 x i32]* %retval.full, align 4
+  ret [2 x i32] %i1
+}
+
+define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args(i32* nocapture nonnull readonly %data, i64 %n) {
+; CHECK-LABEL: @all_parts_of_alloca_used_in_call_with_multiple_args(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
+; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-NEXT:    store i32 0, i32* [[DOTFCA_0_GEP]], align 4
+; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-NEXT:    store i32 0, i32* [[DOTFCA_1_GEP]], align 4
+; CHECK-NEXT:    [[RETVAL_BASE:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i64 0, i64 0
+; CHECK-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i64 0, i64 1
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
+; CHECK-NEXT:    [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4
+; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-NEXT:    store i32 [[RDX_INC]], i32* [[RETVAL]], align 4
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(i32* nocapture nonnull [[RETVAL]], i32* nocapture nonnull [[RETVAL_BASE]])
+; CHECK-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, i32* [[I1_FCA_0_GEP]], align 4
+; CHECK-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] undef, i32 [[I1_FCA_0_LOAD]], 0
+; CHECK-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, i32* [[I1_FCA_1_GEP]], align 4
+; CHECK-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
+; CHECK-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
+;
+; CHECK-OPAQUE-LABEL: @all_parts_of_alloca_used_in_call_with_multiple_args(
+; CHECK-OPAQUE-NEXT:  entry:
+; CHECK-OPAQUE-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
+; CHECK-OPAQUE-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[DOTFCA_0_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[DOTFCA_1_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[RETVAL_BASE:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 0
+; CHECK-OPAQUE-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1
+; CHECK-OPAQUE-NEXT:    br label [[LOOP:%.*]]
+; CHECK-OPAQUE:       loop:
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-OPAQUE-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-OPAQUE-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-OPAQUE-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-OPAQUE-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-OPAQUE-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-OPAQUE:       exit:
+; CHECK-OPAQUE-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr nocapture nonnull [[RETVAL]], ptr nocapture nonnull [[RETVAL_BASE]])
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] undef, i32 [[I1_FCA_0_LOAD]], 0
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
+; CHECK-OPAQUE-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
+;
+entry:
+  %retval.full = alloca [2 x i32], align 4
+  store [2 x i32] zeroinitializer, [2 x i32]* %retval.full, align 4
+  %retval.base = getelementptr inbounds [2 x i32], [2 x i32]* %retval.full, i64 0, i64 0
+  %retval = getelementptr inbounds [2 x i32], [2 x i32]* %retval.full, i64 0, i64 1
+  br label %loop
+
+loop:
+  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
+  %arrayidx = getelementptr inbounds i32, i32* %data, i64 %indvars.iv
+  %ld = load i32, i32* %arrayidx, align 4
+  %rdx = load i32, i32* %retval, align 4
+  %rdx.inc = add nsw i32 %rdx, %ld
+  store i32 %rdx.inc, i32* %retval, align 4
+  %indvars.iv.next = add nsw i64 %indvars.iv, 1
+  %exitcond = icmp ne i64 %indvars.iv.next, %n
+  br i1 %exitcond, label %loop, label %exit
+
+exit:
+  %i0 = call i32 @user_of_alloca_with_multiple_args(i32* nocapture nonnull %retval, i32* nocapture nonnull %retval.base)
+  %i1 = load [2 x i32], [2 x i32]* %retval.full, align 4
+  ret [2 x i32] %i1
+}
+
+define [2 x i32] @part_of_alloca_used_in_call_with_multiple_args(i32* nocapture nonnull readonly %data, i64 %n) {
+; CHECK-LABEL: @part_of_alloca_used_in_call_with_multiple_args(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
+; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-NEXT:    store i32 0, i32* [[DOTFCA_0_GEP]], align 4
+; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-NEXT:    store i32 0, i32* [[DOTFCA_1_GEP]], align 4
+; CHECK-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i64 0, i64 1
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
+; CHECK-NEXT:    [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4
+; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-NEXT:    store i32 [[RDX_INC]], i32* [[RETVAL]], align 4
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(i32* nocapture nonnull [[RETVAL]], i32* nocapture nonnull [[RETVAL]])
+; CHECK-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, i32* [[I1_FCA_0_GEP]], align 4
+; CHECK-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] undef, i32 [[I1_FCA_0_LOAD]], 0
+; CHECK-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, i32* [[I1_FCA_1_GEP]], align 4
+; CHECK-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
+; CHECK-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
+;
+; CHECK-OPAQUE-LABEL: @part_of_alloca_used_in_call_with_multiple_args(
+; CHECK-OPAQUE-NEXT:  entry:
+; CHECK-OPAQUE-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
+; CHECK-OPAQUE-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[DOTFCA_0_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[DOTFCA_1_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1
+; CHECK-OPAQUE-NEXT:    br label [[LOOP:%.*]]
+; CHECK-OPAQUE:       loop:
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-OPAQUE-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-OPAQUE-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-OPAQUE-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-OPAQUE-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-OPAQUE-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-OPAQUE:       exit:
+; CHECK-OPAQUE-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr nocapture nonnull [[RETVAL]], ptr nocapture nonnull [[RETVAL]])
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] undef, i32 [[I1_FCA_0_LOAD]], 0
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
+; CHECK-OPAQUE-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
+;
+entry:
+  %retval.full = alloca [2 x i32], align 4
+  store [2 x i32] zeroinitializer, [2 x i32]* %retval.full, align 4
+  %retval = getelementptr inbounds [2 x i32], [2 x i32]* %retval.full, i64 0, i64 1
+  br label %loop
+
+loop:
+  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
+  %arrayidx = getelementptr inbounds i32, i32* %data, i64 %indvars.iv
+  %ld = load i32, i32* %arrayidx, align 4
+  %rdx = load i32, i32* %retval, align 4
+  %rdx.inc = add nsw i32 %rdx, %ld
+  store i32 %rdx.inc, i32* %retval, align 4
+  %indvars.iv.next = add nsw i64 %indvars.iv, 1
+  %exitcond = icmp ne i64 %indvars.iv.next, %n
+  br i1 %exitcond, label %loop, label %exit
+
+exit:
+  %i0 = call i32 @user_of_alloca_with_multiple_args(i32* nocapture nonnull %retval, i32* nocapture nonnull %retval)
+  %i1 = load [2 x i32], [2 x i32]* %retval.full, align 4
+  ret [2 x i32] %i1
+}
+
+define [2 x i32] @all_parts_of_alloca_used_in_calls_with_multiple_args(i32* nocapture nonnull readonly %data, i64 %n) {
+; CHECK-LABEL: @all_parts_of_alloca_used_in_calls_with_multiple_args(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
+; CHECK-NEXT:    [[SOME_ANOTHER_ALLOCA_FULL:%.*]] = alloca [42 x i32], align 4
+; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-NEXT:    store i32 0, i32* [[DOTFCA_0_GEP]], align 4
+; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-NEXT:    store i32 0, i32* [[DOTFCA_1_GEP]], align 4
+; CHECK-NEXT:    [[RETVAL_BASE:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i64 0, i64 0
+; CHECK-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i64 0, i64 1
+; CHECK-NEXT:    [[SOME_ANOTHER_ALLOCA:%.*]] = getelementptr inbounds [42 x i32], [42 x i32]* [[SOME_ANOTHER_ALLOCA_FULL]], i64 0, i64 0
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
+; CHECK-NEXT:    [[RDX:%.*]] = load i32, i32* [[RETVAL]], align 4
+; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-NEXT:    store i32 [[RDX_INC]], i32* [[RETVAL]], align 4
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(i32* nocapture nonnull [[RETVAL]], i32* nocapture nonnull [[RETVAL_BASE]])
+; CHECK-NEXT:    [[I1:%.*]] = call i32 @user_of_alloca_with_multiple_args(i32* nocapture nonnull [[RETVAL_BASE]], i32* nocapture nonnull [[RETVAL]])
+; CHECK-NEXT:    [[I2:%.*]] = call i32 @capture_of_alloca(i32* [[SOME_ANOTHER_ALLOCA]])
+; CHECK-NEXT:    [[I3_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-NEXT:    [[I3_FCA_0_LOAD:%.*]] = load i32, i32* [[I3_FCA_0_GEP]], align 4
+; CHECK-NEXT:    [[I3_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] undef, i32 [[I3_FCA_0_LOAD]], 0
+; CHECK-NEXT:    [[I3_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-NEXT:    [[I3_FCA_1_LOAD:%.*]] = load i32, i32* [[I3_FCA_1_GEP]], align 4
+; CHECK-NEXT:    [[I3_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I3_FCA_0_INSERT]], i32 [[I3_FCA_1_LOAD]], 1
+; CHECK-NEXT:    ret [2 x i32] [[I3_FCA_1_INSERT]]
+;
+; CHECK-OPAQUE-LABEL: @all_parts_of_alloca_used_in_calls_with_multiple_args(
+; CHECK-OPAQUE-NEXT:  entry:
+; CHECK-OPAQUE-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
+; CHECK-OPAQUE-NEXT:    [[SOME_ANOTHER_ALLOCA_FULL:%.*]] = alloca [42 x i32], align 4
+; CHECK-OPAQUE-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[DOTFCA_0_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-OPAQUE-NEXT:    store i32 0, ptr [[DOTFCA_1_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[RETVAL_BASE:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 0
+; CHECK-OPAQUE-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1
+; CHECK-OPAQUE-NEXT:    [[SOME_ANOTHER_ALLOCA:%.*]] = getelementptr inbounds [42 x i32], ptr [[SOME_ANOTHER_ALLOCA_FULL]], i64 0, i64 0
+; CHECK-OPAQUE-NEXT:    br label [[LOOP:%.*]]
+; CHECK-OPAQUE:       loop:
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-OPAQUE-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
+; CHECK-OPAQUE-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
+; CHECK-OPAQUE-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
+; CHECK-OPAQUE-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-OPAQUE-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
+; CHECK-OPAQUE-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-OPAQUE:       exit:
+; CHECK-OPAQUE-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr nocapture nonnull [[RETVAL]], ptr nocapture nonnull [[RETVAL_BASE]])
+; CHECK-OPAQUE-NEXT:    [[I1:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr nocapture nonnull [[RETVAL_BASE]], ptr nocapture nonnull [[RETVAL]])
+; CHECK-OPAQUE-NEXT:    [[I2:%.*]] = call i32 @capture_of_alloca(ptr [[SOME_ANOTHER_ALLOCA]])
+; CHECK-OPAQUE-NEXT:    [[I3_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
+; CHECK-OPAQUE-NEXT:    [[I3_FCA_0_LOAD:%.*]] = load i32, ptr [[I3_FCA_0_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[I3_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] undef, i32 [[I3_FCA_0_LOAD]], 0
+; CHECK-OPAQUE-NEXT:    [[I3_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
+; CHECK-OPAQUE-NEXT:    [[I3_FCA_1_LOAD:%.*]] = load i32, ptr [[I3_FCA_1_GEP]], align 4
+; CHECK-OPAQUE-NEXT:    [[I3_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I3_FCA_0_INSERT]], i32 [[I3_FCA_1_LOAD]], 1
+; CHECK-OPAQUE-NEXT:    ret [2 x i32] [[I3_FCA_1_INSERT]]
 ;
 entry:
   %retval.full = alloca [2 x i32], align 4
+  %some.another.alloca.full = alloca [42 x i32], align 4
   store [2 x i32] zeroinitializer, [2 x i32]* %retval.full, align 4
+  %retval.base = getelementptr inbounds [2 x i32], [2 x i32]* %retval.full, i64 0, i64 0
   %retval = getelementptr inbounds [2 x i32], [2 x i32]* %retval.full, i64 0, i64 1
+  %some.another.alloca = getelementptr inbounds [42 x i32], [42 x i32]* %some.another.alloca.full, i64 0, i64 0
   br label %loop
 
 loop:
@@ -339,12 +765,15 @@ loop:
   br i1 %exitcond, label %loop, label %exit
 
 exit:
-  %0 = call i32 @user_of_alloca(i32* nocapture nonnull %retval)
-  %1 = load [2 x i32], [2 x i32]* %retval.full, align 4
-  ret [2 x i32] %1
+  %i0 = call i32 @user_of_alloca_with_multiple_args(i32* nocapture nonnull %retval, i32* nocapture nonnull %retval.base)
+  %i1 = call i32 @user_of_alloca_with_multiple_args(i32* nocapture nonnull %retval.base, i32* nocapture nonnull %retval)
+  %i2 = call i32 @capture_of_alloca(i32* %some.another.alloca)
+  %i3 = load [2 x i32], [2 x i32]* %retval.full, align 4
+  ret [2 x i32] %i3
 }
 
 declare dso_local i32 @user_of_alloca(i32* nocapture nonnull)
+declare dso_local i32 @user_of_alloca_with_multiple_args(i32* nocapture nonnull, i32* nocapture nonnull)
 declare dso_local i32 @capture_of_alloca(i32 *nonnull)
 declare dso_local i32 @capture_with_multiple_args(i32* nocapture nonnull, i32* nonnull)
 


        


More information about the llvm-commits mailing list