[llvm] [VPlan] Don't replicate extractvalues that would require extracting lanes from a struct (PR #219941)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 31 03:48:41 PDT 2026
https://github.com/lukel97 updated https://github.com/llvm/llvm-project/pull/219941
>From 5c1876ef020eb451b3c7a2be15d7afec573a0bdc Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Mon, 31 Aug 2026 17:27:51 +0800
Subject: [PATCH] [VPlan] Don't replicate extractvalues that would require
extracting lanes from a struct
In the added test cases, we have an extractvalue in a replicate region:
vector.ph:
WIDEN-INTRINSIC ir<%sincos> = call llvm.sincos(ir<0.000000e+00>)
...
pred.store.if:
EMIT vp<%3> = extractelement ir<%sincos>, ir<0>
CLONE ir<%cos> = extractvalue vp<%3>
CLONE store ir<%cos>, ir<%cos_dst>
However the operand
a) doesn't generate per lane
b) isn't defined in the same replicate region
so replicateRegionByVF tries to extract a lane from a struct, which doesn't work. This fixes it by choosing to widen the extractvalue earlier on when we know we'll end up trying to extract lanes otherwise.
---
.../Transforms/Vectorize/LoopVectorize.cpp | 8 +
.../multiple-result-intrinsics.ll | 49 +++++
.../LoopVectorize/struct-return-replicate.ll | 175 ++++++++++++++++++
3 files changed, 232 insertions(+)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 1f153afd6bedd..0678f74c07c3e 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -6431,6 +6431,14 @@ VPRecipeBuilder::tryToCreateWidenNonPhiRecipe(VPSingleDefRecipe *R,
VPI->getOpcode()) &&
"Should have been handled prior to this!");
+ // We can only replicate an extractvalue if its operand generates per lane in
+ // the same replicate region.
+ if (VPI->getOpcode() == Instruction::ExtractValue)
+ if (VPRecipeBase *OpR = VPI->getOperand(0)->getDefiningRecipe())
+ if (!vputils::doesGeneratePerAllLanes(OpR) ||
+ OpR->getParent() != VPI->getParent())
+ return tryToWiden(VPI);
+
if (!shouldWiden(Instr, Range))
return nullptr;
diff --git a/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll b/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll
index 8c204f7bb4e32..8a102523bf914 100644
--- a/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll
+++ b/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll
@@ -816,3 +816,52 @@ for.body:
exit:
ret void
}
+
+define void @sincos_predicated_store(i1 %c, double %x, ptr noalias %dst, ptr noalias %cos_dst) {
+; CHECK-LABEL: define void @sincos_predicated_store(
+; CHECK-SAME: i1 [[C:%.*]], double [[X:%.*]], ptr noalias [[DST:%.*]], ptr noalias [[COS_DST:%.*]]) {
+; CHECK: [[ENTRY:.*:]]
+; CHECK: [[VECTOR_PH:.*]]:
+; CHECK: [[TMP0:%.*]] = call { <2 x double>, <2 x double> } @llvm.sincos.v2f64(<2 x double> [[BROADCAST_SPLAT:%.*]])
+; CHECK: [[TMP2:%.*]] = extractvalue { <2 x double>, <2 x double> } [[TMP0]], 1
+; CHECK: [[VECTOR_BODY:.*:]]
+; CHECK: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE2:.*]] ]
+; CHECK: store <2 x double> zeroinitializer, ptr [[TMP3:%.*]], align 8
+; CHECK: br i1 [[TMP1:%.*]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]]
+; CHECK: [[PRED_STORE_IF]]:
+; CHECK: [[TMP4:%.*]] = extractelement <2 x double> [[TMP2]], i64 0
+; CHECK: store double [[TMP4]], ptr [[COS_DST]], align 8
+; CHECK: br label %[[PRED_STORE_CONTINUE]]
+; CHECK: [[PRED_STORE_CONTINUE]]:
+; CHECK: br i1 [[TMP1]], label %[[PRED_STORE_IF1:.*]], label %[[PRED_STORE_CONTINUE2]]
+; CHECK: [[PRED_STORE_IF1]]:
+; CHECK: [[TMP5:%.*]] = extractelement <2 x double> [[TMP2]], i64 1
+; CHECK: store double [[TMP5]], ptr [[COS_DST]], align 8
+; CHECK: br label %[[PRED_STORE_CONTINUE2]]
+; CHECK: [[PRED_STORE_CONTINUE2]]:
+; CHECK: [[MIDDLE_BLOCK:.*:]]
+; CHECK: [[EXIT:.*:]]
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i64 [ %iv.next, %latch ], [ 0, %entry ]
+ %sincos = tail call { double, double } @llvm.sincos.f64(double %x)
+ %gep = getelementptr double, ptr %dst, i64 %iv
+ store double 0.0, ptr %gep
+ br i1 %c, label %latch, label %if
+
+if:
+ %cos = extractvalue { double, double } %sincos, 1
+ store double %cos, ptr %cos_dst
+ br label %latch
+
+latch:
+ %iv.next = add nuw nsw i64 %iv, 1
+ %ec = icmp eq i64 %iv.next, 1024
+ br i1 %ec, label %exit, label %loop
+
+exit:
+ ret void
+}
diff --git a/llvm/test/Transforms/LoopVectorize/struct-return-replicate.ll b/llvm/test/Transforms/LoopVectorize/struct-return-replicate.ll
index 92da4ca663969..c02b82db45514 100644
--- a/llvm/test/Transforms/LoopVectorize/struct-return-replicate.ll
+++ b/llvm/test/Transforms/LoopVectorize/struct-return-replicate.ll
@@ -656,6 +656,181 @@ exit:
ret void
}
+define void @struct_return_predicated_extractvalue(i1 %c, ptr noalias %p, ptr noalias %q) {
+; VF4-LABEL: define void @struct_return_predicated_extractvalue(
+; VF4-SAME: i1 [[C:%.*]], ptr noalias [[P:%.*]], ptr noalias [[Q:%.*]]) {
+; VF4-NEXT: [[ENTRY:.*:]]
+; VF4-NEXT: br label %[[VECTOR_PH:.*]]
+; VF4: [[VECTOR_PH]]:
+; VF4-NEXT: [[TMP0:%.*]] = xor i1 [[C]], true
+; VF4-NEXT: br label %[[VECTOR_BODY:.*]]
+; VF4: [[VECTOR_BODY]]:
+; VF4-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE6:.*]] ]
+; VF4-NEXT: [[TMP1:%.*]] = tail call { float, float } @fn2(float 0.000000e+00) #[[ATTR3]]
+; VF4-NEXT: [[TMP2:%.*]] = tail call { float, float } @fn2(float 0.000000e+00) #[[ATTR3]]
+; VF4-NEXT: [[TMP3:%.*]] = tail call { float, float } @fn2(float 0.000000e+00) #[[ATTR3]]
+; VF4-NEXT: [[TMP4:%.*]] = tail call { float, float } @fn2(float 0.000000e+00) #[[ATTR3]]
+; VF4-NEXT: [[TMP5:%.*]] = extractvalue { float, float } [[TMP1]], 0
+; VF4-NEXT: [[TMP6:%.*]] = insertelement <4 x float> poison, float [[TMP5]], i64 0
+; VF4-NEXT: [[TMP7:%.*]] = insertvalue { <4 x float>, <4 x float> } poison, <4 x float> [[TMP6]], 0
+; VF4-NEXT: [[TMP8:%.*]] = extractvalue { float, float } [[TMP1]], 1
+; VF4-NEXT: [[TMP9:%.*]] = extractvalue { <4 x float>, <4 x float> } [[TMP7]], 1
+; VF4-NEXT: [[TMP10:%.*]] = insertelement <4 x float> [[TMP9]], float [[TMP8]], i64 0
+; VF4-NEXT: [[TMP11:%.*]] = insertvalue { <4 x float>, <4 x float> } [[TMP7]], <4 x float> [[TMP10]], 1
+; VF4-NEXT: [[TMP12:%.*]] = extractvalue { float, float } [[TMP2]], 0
+; VF4-NEXT: [[TMP13:%.*]] = extractvalue { <4 x float>, <4 x float> } [[TMP11]], 0
+; VF4-NEXT: [[TMP14:%.*]] = insertelement <4 x float> [[TMP13]], float [[TMP12]], i64 1
+; VF4-NEXT: [[TMP15:%.*]] = insertvalue { <4 x float>, <4 x float> } [[TMP11]], <4 x float> [[TMP14]], 0
+; VF4-NEXT: [[TMP16:%.*]] = extractvalue { float, float } [[TMP2]], 1
+; VF4-NEXT: [[TMP17:%.*]] = extractvalue { <4 x float>, <4 x float> } [[TMP15]], 1
+; VF4-NEXT: [[TMP18:%.*]] = insertelement <4 x float> [[TMP17]], float [[TMP16]], i64 1
+; VF4-NEXT: [[TMP19:%.*]] = insertvalue { <4 x float>, <4 x float> } [[TMP15]], <4 x float> [[TMP18]], 1
+; VF4-NEXT: [[TMP20:%.*]] = extractvalue { float, float } [[TMP3]], 0
+; VF4-NEXT: [[TMP21:%.*]] = extractvalue { <4 x float>, <4 x float> } [[TMP19]], 0
+; VF4-NEXT: [[TMP22:%.*]] = insertelement <4 x float> [[TMP21]], float [[TMP20]], i64 2
+; VF4-NEXT: [[TMP23:%.*]] = insertvalue { <4 x float>, <4 x float> } [[TMP19]], <4 x float> [[TMP22]], 0
+; VF4-NEXT: [[TMP24:%.*]] = extractvalue { float, float } [[TMP3]], 1
+; VF4-NEXT: [[TMP25:%.*]] = extractvalue { <4 x float>, <4 x float> } [[TMP23]], 1
+; VF4-NEXT: [[TMP26:%.*]] = insertelement <4 x float> [[TMP25]], float [[TMP24]], i64 2
+; VF4-NEXT: [[TMP27:%.*]] = insertvalue { <4 x float>, <4 x float> } [[TMP23]], <4 x float> [[TMP26]], 1
+; VF4-NEXT: [[TMP28:%.*]] = extractvalue { float, float } [[TMP4]], 0
+; VF4-NEXT: [[TMP29:%.*]] = extractvalue { <4 x float>, <4 x float> } [[TMP27]], 0
+; VF4-NEXT: [[TMP30:%.*]] = insertelement <4 x float> [[TMP29]], float [[TMP28]], i64 3
+; VF4-NEXT: [[TMP31:%.*]] = insertvalue { <4 x float>, <4 x float> } [[TMP27]], <4 x float> [[TMP30]], 0
+; VF4-NEXT: [[TMP32:%.*]] = extractvalue { float, float } [[TMP4]], 1
+; VF4-NEXT: [[TMP33:%.*]] = extractvalue { <4 x float>, <4 x float> } [[TMP31]], 1
+; VF4-NEXT: [[TMP34:%.*]] = insertelement <4 x float> [[TMP33]], float [[TMP32]], i64 3
+; VF4-NEXT: [[TMP35:%.*]] = insertvalue { <4 x float>, <4 x float> } [[TMP31]], <4 x float> [[TMP34]], 1
+; VF4-NEXT: store float 0.000000e+00, ptr [[P]], align 4
+; VF4-NEXT: [[TMP36:%.*]] = extractvalue { <4 x float>, <4 x float> } [[TMP35]], 1
+; VF4-NEXT: br i1 [[TMP0]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]]
+; VF4: [[PRED_STORE_IF]]:
+; VF4-NEXT: [[TMP37:%.*]] = extractelement <4 x float> [[TMP36]], i64 0
+; VF4-NEXT: store float [[TMP37]], ptr [[Q]], align 4
+; VF4-NEXT: br label %[[PRED_STORE_CONTINUE]]
+; VF4: [[PRED_STORE_CONTINUE]]:
+; VF4-NEXT: br i1 [[TMP0]], label %[[PRED_STORE_IF1:.*]], label %[[PRED_STORE_CONTINUE2:.*]]
+; VF4: [[PRED_STORE_IF1]]:
+; VF4-NEXT: [[TMP38:%.*]] = extractelement <4 x float> [[TMP36]], i64 1
+; VF4-NEXT: store float [[TMP38]], ptr [[Q]], align 4
+; VF4-NEXT: br label %[[PRED_STORE_CONTINUE2]]
+; VF4: [[PRED_STORE_CONTINUE2]]:
+; VF4-NEXT: br i1 [[TMP0]], label %[[PRED_STORE_IF3:.*]], label %[[PRED_STORE_CONTINUE4:.*]]
+; VF4: [[PRED_STORE_IF3]]:
+; VF4-NEXT: [[TMP39:%.*]] = extractelement <4 x float> [[TMP36]], i64 2
+; VF4-NEXT: store float [[TMP39]], ptr [[Q]], align 4
+; VF4-NEXT: br label %[[PRED_STORE_CONTINUE4]]
+; VF4: [[PRED_STORE_CONTINUE4]]:
+; VF4-NEXT: br i1 [[TMP0]], label %[[PRED_STORE_IF5:.*]], label %[[PRED_STORE_CONTINUE6]]
+; VF4: [[PRED_STORE_IF5]]:
+; VF4-NEXT: [[TMP40:%.*]] = extractelement <4 x float> [[TMP36]], i64 3
+; VF4-NEXT: store float [[TMP40]], ptr [[Q]], align 4
+; VF4-NEXT: br label %[[PRED_STORE_CONTINUE6]]
+; VF4: [[PRED_STORE_CONTINUE6]]:
+; VF4-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; VF4-NEXT: [[TMP41:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
+; VF4-NEXT: br i1 [[TMP41]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
+; VF4: [[MIDDLE_BLOCK]]:
+;
+; VF2IC2-LABEL: define void @struct_return_predicated_extractvalue(
+; VF2IC2-SAME: i1 [[C:%.*]], ptr noalias [[P:%.*]], ptr noalias [[Q:%.*]]) {
+; VF2IC2-NEXT: [[ENTRY:.*:]]
+; VF2IC2-NEXT: br label %[[VECTOR_PH:.*]]
+; VF2IC2: [[VECTOR_PH]]:
+; VF2IC2-NEXT: [[TMP0:%.*]] = xor i1 [[C]], true
+; VF2IC2-NEXT: br label %[[VECTOR_BODY:.*]]
+; VF2IC2: [[VECTOR_BODY]]:
+; VF2IC2-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE6:.*]] ]
+; VF2IC2-NEXT: [[TMP1:%.*]] = tail call { float, float } @fn2(float 0.000000e+00) #[[ATTR3]]
+; VF2IC2-NEXT: [[TMP2:%.*]] = tail call { float, float } @fn2(float 0.000000e+00) #[[ATTR3]]
+; VF2IC2-NEXT: [[TMP3:%.*]] = extractvalue { float, float } [[TMP1]], 0
+; VF2IC2-NEXT: [[TMP4:%.*]] = insertelement <2 x float> poison, float [[TMP3]], i64 0
+; VF2IC2-NEXT: [[TMP5:%.*]] = insertvalue { <2 x float>, <2 x float> } poison, <2 x float> [[TMP4]], 0
+; VF2IC2-NEXT: [[TMP6:%.*]] = extractvalue { float, float } [[TMP1]], 1
+; VF2IC2-NEXT: [[TMP7:%.*]] = extractvalue { <2 x float>, <2 x float> } [[TMP5]], 1
+; VF2IC2-NEXT: [[TMP8:%.*]] = insertelement <2 x float> [[TMP7]], float [[TMP6]], i64 0
+; VF2IC2-NEXT: [[TMP9:%.*]] = insertvalue { <2 x float>, <2 x float> } [[TMP5]], <2 x float> [[TMP8]], 1
+; VF2IC2-NEXT: [[TMP10:%.*]] = extractvalue { float, float } [[TMP2]], 0
+; VF2IC2-NEXT: [[TMP11:%.*]] = extractvalue { <2 x float>, <2 x float> } [[TMP9]], 0
+; VF2IC2-NEXT: [[TMP12:%.*]] = insertelement <2 x float> [[TMP11]], float [[TMP10]], i64 1
+; VF2IC2-NEXT: [[TMP13:%.*]] = insertvalue { <2 x float>, <2 x float> } [[TMP9]], <2 x float> [[TMP12]], 0
+; VF2IC2-NEXT: [[TMP14:%.*]] = extractvalue { float, float } [[TMP2]], 1
+; VF2IC2-NEXT: [[TMP15:%.*]] = extractvalue { <2 x float>, <2 x float> } [[TMP13]], 1
+; VF2IC2-NEXT: [[TMP16:%.*]] = insertelement <2 x float> [[TMP15]], float [[TMP14]], i64 1
+; VF2IC2-NEXT: [[TMP17:%.*]] = insertvalue { <2 x float>, <2 x float> } [[TMP13]], <2 x float> [[TMP16]], 1
+; VF2IC2-NEXT: [[TMP18:%.*]] = tail call { float, float } @fn2(float 0.000000e+00) #[[ATTR3]]
+; VF2IC2-NEXT: [[TMP19:%.*]] = tail call { float, float } @fn2(float 0.000000e+00) #[[ATTR3]]
+; VF2IC2-NEXT: [[TMP20:%.*]] = extractvalue { float, float } [[TMP18]], 0
+; VF2IC2-NEXT: [[TMP21:%.*]] = insertelement <2 x float> poison, float [[TMP20]], i64 0
+; VF2IC2-NEXT: [[TMP22:%.*]] = insertvalue { <2 x float>, <2 x float> } poison, <2 x float> [[TMP21]], 0
+; VF2IC2-NEXT: [[TMP23:%.*]] = extractvalue { float, float } [[TMP18]], 1
+; VF2IC2-NEXT: [[TMP24:%.*]] = extractvalue { <2 x float>, <2 x float> } [[TMP22]], 1
+; VF2IC2-NEXT: [[TMP25:%.*]] = insertelement <2 x float> [[TMP24]], float [[TMP23]], i64 0
+; VF2IC2-NEXT: [[TMP26:%.*]] = insertvalue { <2 x float>, <2 x float> } [[TMP22]], <2 x float> [[TMP25]], 1
+; VF2IC2-NEXT: [[TMP27:%.*]] = extractvalue { float, float } [[TMP19]], 0
+; VF2IC2-NEXT: [[TMP28:%.*]] = extractvalue { <2 x float>, <2 x float> } [[TMP26]], 0
+; VF2IC2-NEXT: [[TMP29:%.*]] = insertelement <2 x float> [[TMP28]], float [[TMP27]], i64 1
+; VF2IC2-NEXT: [[TMP30:%.*]] = insertvalue { <2 x float>, <2 x float> } [[TMP26]], <2 x float> [[TMP29]], 0
+; VF2IC2-NEXT: [[TMP31:%.*]] = extractvalue { float, float } [[TMP19]], 1
+; VF2IC2-NEXT: [[TMP32:%.*]] = extractvalue { <2 x float>, <2 x float> } [[TMP30]], 1
+; VF2IC2-NEXT: [[TMP33:%.*]] = insertelement <2 x float> [[TMP32]], float [[TMP31]], i64 1
+; VF2IC2-NEXT: [[TMP34:%.*]] = insertvalue { <2 x float>, <2 x float> } [[TMP30]], <2 x float> [[TMP33]], 1
+; VF2IC2-NEXT: store float 0.000000e+00, ptr [[P]], align 4
+; VF2IC2-NEXT: [[TMP35:%.*]] = extractvalue { <2 x float>, <2 x float> } [[TMP17]], 1
+; VF2IC2-NEXT: [[TMP36:%.*]] = extractvalue { <2 x float>, <2 x float> } [[TMP34]], 1
+; VF2IC2-NEXT: br i1 [[TMP0]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]]
+; VF2IC2: [[PRED_STORE_IF]]:
+; VF2IC2-NEXT: [[TMP37:%.*]] = extractelement <2 x float> [[TMP35]], i64 0
+; VF2IC2-NEXT: store float [[TMP37]], ptr [[Q]], align 4
+; VF2IC2-NEXT: br label %[[PRED_STORE_CONTINUE]]
+; VF2IC2: [[PRED_STORE_CONTINUE]]:
+; VF2IC2-NEXT: br i1 [[TMP0]], label %[[PRED_STORE_IF1:.*]], label %[[PRED_STORE_CONTINUE2:.*]]
+; VF2IC2: [[PRED_STORE_IF1]]:
+; VF2IC2-NEXT: [[TMP38:%.*]] = extractelement <2 x float> [[TMP35]], i64 1
+; VF2IC2-NEXT: store float [[TMP38]], ptr [[Q]], align 4
+; VF2IC2-NEXT: br label %[[PRED_STORE_CONTINUE2]]
+; VF2IC2: [[PRED_STORE_CONTINUE2]]:
+; VF2IC2-NEXT: br i1 [[TMP0]], label %[[PRED_STORE_IF3:.*]], label %[[PRED_STORE_CONTINUE4:.*]]
+; VF2IC2: [[PRED_STORE_IF3]]:
+; VF2IC2-NEXT: [[TMP39:%.*]] = extractelement <2 x float> [[TMP36]], i64 0
+; VF2IC2-NEXT: store float [[TMP39]], ptr [[Q]], align 4
+; VF2IC2-NEXT: br label %[[PRED_STORE_CONTINUE4]]
+; VF2IC2: [[PRED_STORE_CONTINUE4]]:
+; VF2IC2-NEXT: br i1 [[TMP0]], label %[[PRED_STORE_IF5:.*]], label %[[PRED_STORE_CONTINUE6]]
+; VF2IC2: [[PRED_STORE_IF5]]:
+; VF2IC2-NEXT: [[TMP40:%.*]] = extractelement <2 x float> [[TMP36]], i64 1
+; VF2IC2-NEXT: store float [[TMP40]], ptr [[Q]], align 4
+; VF2IC2-NEXT: br label %[[PRED_STORE_CONTINUE6]]
+; VF2IC2: [[PRED_STORE_CONTINUE6]]:
+; VF2IC2-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; VF2IC2-NEXT: [[TMP41:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
+; VF2IC2-NEXT: br i1 [[TMP41]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
+; VF2IC2: [[MIDDLE_BLOCK]]:
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i64 [ %iv.next, %latch ], [ 0, %entry ]
+ %call = tail call { float, float } @fn2(float 0.0) #3
+ %gep = getelementptr float, ptr %p, i64 %iv
+ store float 0.0, ptr %p
+ br i1 %c, label %latch, label %if
+
+if:
+ %val = extractvalue { float, float } %call, 1
+ store float %val, ptr %q
+ br label %latch
+
+latch:
+ %iv.next = add nuw nsw i64 %iv, 1
+ %ec = icmp eq i64 %iv.next, 1024
+ br i1 %ec, label %exit, label %loop
+
+exit:
+ ret void
+}
+
declare { i64 } @fn1(float)
declare { float, float } @fn2(float)
declare { i32, i32, i32 } @fn3(i32)
More information about the llvm-commits
mailing list