[llvm] Imprecise switch case (PR #82795)

via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 23 09:05:14 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Acim Maravic (Acim-Maravic)

<details>
<summary>Changes</summary>

Next step is to gather all blocks that can be safely merged be merged into 21 in order for me to create selects and to allow non constant values in helpers.

---

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


6 Files Affected:

- (modified) llvm/include/llvm/Transforms/Utils/SimplifyCFGOptions.h (+5) 
- (modified) llvm/lib/Passes/PassBuilder.cpp (+2) 
- (modified) llvm/lib/Passes/PassRegistry.def (+1) 
- (modified) llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp (+6) 
- (modified) llvm/lib/Transforms/Utils/SimplifyCFG.cpp (+55-8) 
- (added) llvm/test/Transforms/SimplifyCFG/AMDGPU/switch-to-select.ll (+312) 


``````````diff
diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyCFGOptions.h b/llvm/include/llvm/Transforms/Utils/SimplifyCFGOptions.h
index 8008fc6e8422d3..cb3ef663408153 100644
--- a/llvm/include/llvm/Transforms/Utils/SimplifyCFGOptions.h
+++ b/llvm/include/llvm/Transforms/Utils/SimplifyCFGOptions.h
@@ -30,6 +30,7 @@ struct SimplifyCFGOptions {
   bool SinkCommonInsts = false;
   bool SimplifyCondBranch = true;
   bool SpeculateBlocks = true;
+  bool ConvertSwitchToSelect = false;
 
   AssumptionCache *AC = nullptr;
 
@@ -46,6 +47,10 @@ struct SimplifyCFGOptions {
     ConvertSwitchRangeToICmp = B;
     return *this;
   }
+  SimplifyCFGOptions &convertSwitchToSelect(bool B) {
+    ConvertSwitchToSelect = B;
+    return *this;
+  }
   SimplifyCFGOptions &convertSwitchToLookupTable(bool B) {
     ConvertSwitchToLookupTable = B;
     return *this;
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index c934ec42f6eb15..360dc4da3ca91d 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -819,6 +819,8 @@ Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
       Result.forwardSwitchCondToPhi(Enable);
     } else if (ParamName == "switch-range-to-icmp") {
       Result.convertSwitchRangeToICmp(Enable);
+    } else if (ParamName == "switch-to-select") {
+      Result.convertSwitchToSelect(Enable);
     } else if (ParamName == "switch-to-lookup") {
       Result.convertSwitchToLookupTable(Enable);
     } else if (ParamName == "keep-loops") {
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 44511800ccff8d..a3783afdf3be68 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -548,6 +548,7 @@ FUNCTION_PASS_WITH_PARAMS(
     "no-forward-switch-cond;forward-switch-cond;no-switch-range-to-icmp;"
     "switch-range-to-icmp;no-switch-to-lookup;switch-to-lookup;no-keep-loops;"
     "keep-loops;no-hoist-common-insts;hoist-common-insts;no-sink-common-insts;"
+    "switch-to-select;"
     "sink-common-insts;bonus-inst-threshold=N")
 FUNCTION_PASS_WITH_PARAMS(
     "speculative-execution", "SpeculativeExecutionPass",
diff --git a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
index 7017f6adf3a2bb..eafedef2af7d2e 100644
--- a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -61,6 +61,10 @@ static cl::opt<bool> UserSwitchRangeToICmp(
     cl::desc(
         "Convert switches into an integer range comparison (default = false)"));
 
+static cl::opt<bool> UserSwitchToSelect(
+    "switch-to-select", cl::Hidden, cl::init(false),
+    cl::desc("Convert switches into icmp + select (default = false)"));
+
 static cl::opt<bool> UserSwitchToLookup(
     "switch-to-lookup", cl::Hidden, cl::init(false),
     cl::desc("Convert switches to lookup tables (default = false)"));
@@ -323,6 +327,8 @@ static void applyCommandLineOverridesToOptions(SimplifyCFGOptions &Options) {
     Options.HoistCommonInsts = UserHoistCommonInsts;
   if (UserSinkCommonInsts.getNumOccurrences())
     Options.SinkCommonInsts = UserSinkCommonInsts;
+  if (UserSwitchToSelect.getNumOccurrences())
+    Options.ConvertSwitchToSelect = UserSwitchToSelect;
 }
 
 SimplifyCFGPass::SimplifyCFGPass() {
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 254795ec244534..3572c2fe68a538 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -5916,7 +5916,7 @@ static bool initializeUniqueCases(SwitchInst *SI, PHINode *&PHI,
       return false;
 
     // Only one value per case is permitted.
-    if (Results.size() > 1)
+    if (Results.size() > 3) // How many PHI instructions are hendled
       return false;
 
     // Add the case->result mapping to UniqueResults.
@@ -5953,12 +5953,31 @@ static bool initializeUniqueCases(SwitchInst *SI, PHINode *&PHI,
   return true;
 }
 
+Value *createSelectChain(Value *Condition, Constant *DefaultResult,
+                         const SwitchCaseResultVectorTy &ResultVector,
+                         unsigned StartIndex, IRBuilder<> &Builder) {
+  if (StartIndex >= ResultVector.size() && DefaultResult) {
+    return DefaultResult;
+  }
+
+  ConstantInt *CurrentCase = ResultVector[StartIndex].second[0];
+  Value *ValueCompare =
+      Builder.CreateICmpEQ(Condition, CurrentCase, "switch.selectcmp");
+
+  Value *NextSelect = createSelectChain(Condition, DefaultResult, ResultVector,
+                                        StartIndex + 1, Builder);
+
+  return Builder.CreateSelect(ValueCompare, ResultVector[StartIndex].first,
+                              NextSelect, "switch.select");
+}
+
 // Helper function that checks if it is possible to transform a switch with only
 // two cases (or two cases + default) that produces a result into a select.
 // TODO: Handle switches with more than 2 cases that map to the same result.
 static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
                                  Constant *DefaultResult, Value *Condition,
-                                 IRBuilder<> &Builder) {
+                                 IRBuilder<> &Builder,
+                                 bool IsComplexSwitchTransform = false) {
   // If we are selecting between only two cases transform into a simple
   // select or a two-way select if default is possible.
   // Example:
@@ -5967,6 +5986,22 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
   //   case 20: return 2;   ---->  %2 = icmp eq i32 %a, 20
   //   default: return 4;          %3 = select i1 %2, i32 2, i32 %1
   // }
+
+  if (IsComplexSwitchTransform) {
+    bool IsSizeOkay = true;
+
+    for (int i = 0; i < ResultVector.size(); i++)
+      if (ResultVector[i].second.size() != 1)
+        IsSizeOkay = false;
+
+    if (IsSizeOkay && ResultVector.size() > 2) {
+      Value *FinalSelect =
+          createSelectChain(Condition, DefaultResult, ResultVector, 0, Builder);
+      if (FinalSelect)
+        return FinalSelect;
+    }
+  }
+
   if (ResultVector.size() == 2 && ResultVector[0].second.size() == 1 &&
       ResultVector[1].second.size() == 1) {
     ConstantInt *FirstCase = ResultVector[0].second[0];
@@ -6071,21 +6106,29 @@ static void removeSwitchAfterSelectFold(SwitchInst *SI, PHINode *PHI,
 /// switch with a select. Returns true if the fold was made.
 static bool trySwitchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
                               DomTreeUpdater *DTU, const DataLayout &DL,
-                              const TargetTransformInfo &TTI) {
+                              const TargetTransformInfo &TTI,
+                              bool IsComplexSwitchTransform = false) {
   Value *const Cond = SI->getCondition();
   PHINode *PHI = nullptr;
   BasicBlock *CommonDest = nullptr;
   Constant *DefaultResult;
   SwitchCaseResultVectorTy UniqueResults;
   // Collect all the cases that will deliver the same value from the switch.
-  if (!initializeUniqueCases(SI, PHI, CommonDest, UniqueResults, DefaultResult,
-                             DL, TTI, /*MaxUniqueResults*/ 2))
+  if (!initializeUniqueCases(
+          SI, PHI, CommonDest, UniqueResults, DefaultResult, DL, TTI,
+          /*MaxUniqueResults*/ 7)) // I think that the next step is to expand
+                                   // this function to return a list of basic
+                                   // blocks that can be merged
     return false;
 
   assert(PHI != nullptr && "PHI for value select not found");
   Builder.SetInsertPoint(SI);
-  Value *SelectValue =
-      foldSwitchToSelect(UniqueResults, DefaultResult, Cond, Builder);
+  Value *SelectValue = foldSwitchToSelect(
+      UniqueResults, DefaultResult, Cond, Builder,
+      IsComplexSwitchTransform); //  Afterwards this function should just merge
+                                 //  these blocks with the predaccessor of the
+                                 //  switch. Also, UniqueResults would no longer
+                                 //  be just constants
   if (!SelectValue)
     return false;
 
@@ -7028,7 +7071,11 @@ bool SimplifyCFGOpt::simplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
   if (eliminateDeadSwitchCases(SI, DTU, Options.AC, DL))
     return requestResimplify();
 
-  if (trySwitchToSelect(SI, Builder, DTU, DL, TTI))
+  bool IsSwitchToSelect = false;
+  if (Options.ConvertSwitchToSelect)
+    IsSwitchToSelect = true;
+
+  if (trySwitchToSelect(SI, Builder, DTU, DL, TTI, IsSwitchToSelect))
     return requestResimplify();
 
   if (Options.ForwardSwitchCondToPhi && ForwardSwitchConditionToPHI(SI))
diff --git a/llvm/test/Transforms/SimplifyCFG/AMDGPU/switch-to-select.ll b/llvm/test/Transforms/SimplifyCFG/AMDGPU/switch-to-select.ll
new file mode 100644
index 00000000000000..fa783283b881f1
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/AMDGPU/switch-to-select.ll
@@ -0,0 +1,312 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=simplifycfg -switch-to-select < %s | FileCheck -check-prefix=ALL %s
+
+
+define float @SimpleTestTwoCasesAndDefault(<2 x float> noundef %PerspInterpCenter, i32 inreg noundef %PrimMask) {
+; ALL-LABEL: @SimpleTestTwoCasesAndDefault(
+; ALL-NEXT:  .entry:
+; ALL-NEXT:    [[PERSPINTERPCENTER_I1:%.*]] = extractelement <2 x float> [[PERSPINTERPCENTER:%.*]], i64 1
+; ALL-NEXT:    [[PERSPINTERPCENTER_I0:%.*]] = extractelement <2 x float> [[PERSPINTERPCENTER]], i64 0
+; ALL-NEXT:    [[TMP0:%.*]] = call float @llvm.amdgcn.interp.p1(float [[PERSPINTERPCENTER_I0]], i32 immarg 1, i32 immarg 0, i32 [[PRIMMASK:%.*]])
+; ALL-NEXT:    [[TMP1:%.*]] = call float @llvm.amdgcn.interp.p2(float [[TMP0]], float [[PERSPINTERPCENTER_I1]], i32 immarg 1, i32 immarg 0, i32 [[PRIMMASK]])
+; ALL-NEXT:    [[TMP2:%.*]] = fmul reassoc nnan nsz arcp contract afn float [[TMP1]], 3.000000e+00
+; ALL-NEXT:    [[TMP3:%.*]] = call reassoc nnan nsz arcp contract afn float @llvm.floor.f32(float [[TMP2]])
+; ALL-NEXT:    [[TMP4:%.*]] = fptosi float [[TMP3]] to i32
+; ALL-NEXT:    [[DOTFR:%.*]] = freeze i32 [[TMP4]]
+; ALL-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[DOTFR]], 1
+; ALL-NEXT:    br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP12:%.*]]
+; ALL:       6:
+; ALL-NEXT:    [[TMP7:%.*]] = call float @llvm.amdgcn.interp.p1(float [[PERSPINTERPCENTER_I0]], i32 immarg 0, i32 immarg 0, i32 [[PRIMMASK]])
+; ALL-NEXT:    [[TMP8:%.*]] = call float @llvm.amdgcn.interp.p2(float [[TMP7]], float [[PERSPINTERPCENTER_I1]], i32 immarg 0, i32 immarg 0, i32 [[PRIMMASK]])
+; ALL-NEXT:    [[TMP9:%.*]] = fmul reassoc nnan nsz arcp contract afn float [[TMP8]], 4.000000e+00
+; ALL-NEXT:    [[TMP10:%.*]] = call reassoc nnan nsz arcp contract afn float @llvm.floor.f32(float [[TMP9]])
+; ALL-NEXT:    [[TMP11:%.*]] = fptosi float [[TMP10]] to i32
+; ALL-NEXT:    [[COND_FREEZE1:%.*]] = freeze i32 [[TMP11]]
+; ALL-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[COND_FREEZE1]], 1
+; ALL-NEXT:    [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], float 2.000000e+00, float 4.000000e+00
+; ALL-NEXT:    [[SWITCH_SELECTCMP1:%.*]] = icmp eq i32 [[COND_FREEZE1]], 0
+; ALL-NEXT:    [[SWITCH_SELECT2:%.*]] = select i1 [[SWITCH_SELECTCMP1]], float 1.000000e+00, float [[SWITCH_SELECT]]
+; ALL-NEXT:    br label [[TMP12]]
+; ALL:       12:
+; ALL-NEXT:    [[SAMPLEPOS_1_I0:%.*]] = phi float [ 0.000000e+00, [[DOTENTRY:%.*]] ], [ [[SWITCH_SELECT2]], [[TMP6]] ]
+; ALL-NEXT:    ret float [[SAMPLEPOS_1_I0]]
+;
+.entry:
+  %PerspInterpCenter.i1 = extractelement <2 x float> %PerspInterpCenter, i64 1
+  %PerspInterpCenter.i0 = extractelement <2 x float> %PerspInterpCenter, i64 0
+  %0 = call float @llvm.amdgcn.interp.p1(float %PerspInterpCenter.i0, i32 immarg 1, i32 immarg 0, i32 %PrimMask) #1
+  %1 = call float @llvm.amdgcn.interp.p2(float %0, float %PerspInterpCenter.i1, i32 immarg 1, i32 immarg 0, i32 %PrimMask) #1
+  %2 = fmul reassoc nnan nsz arcp contract afn float %1, 3.000000e00
+  %3 = call reassoc nnan nsz arcp contract afn float @llvm.floor.f32(float %2)
+  %4 = fptosi float %3 to i32
+  %.fr = freeze i32 %4
+  %5 = icmp eq i32 %.fr, 1
+  br i1 %5, label %6, label %14
+
+6:                                                ; preds = %.entry
+  %7 = call float @llvm.amdgcn.interp.p1(float %PerspInterpCenter.i0, i32 immarg 0, i32 immarg 0, i32 %PrimMask) #1
+  %8 = call float @llvm.amdgcn.interp.p2(float %7, float %PerspInterpCenter.i1, i32 immarg 0, i32 immarg 0, i32 %PrimMask) #1
+  %9 = fmul reassoc nnan nsz arcp contract afn float %8, 4.000000e00
+  %10 = call reassoc nnan nsz arcp contract afn float @llvm.floor.f32(float %9)
+  %11 = fptosi float %10 to i32
+  %cond.freeze1 = freeze i32 %11
+  switch i32 %cond.freeze1, label %14 [
+  i32 0, label %12
+  i32 1, label %13
+  ]
+
+12:                                               ; preds = %6
+  br label %14
+
+13:                                               ; preds = %6
+  br label %14
+
+14:                                               ; preds = %12, %13, %6, %.entry
+  %samplePos.1.i0 = phi float [ 0.000000e00, %.entry ], [ 2.000000e00, %13 ], [ 1.000000e00, %12 ], [ 4.000000e00, %6 ]
+  ret float %samplePos.1.i0
+}
+
+define float @SimpleTestTwoCases(<2 x float> noundef %PerspInterpCenter, i32 inreg noundef %PrimMask) {
+; ALL-LABEL: @SimpleTestTwoCases(
+; ALL-NEXT:  .entry:
+; ALL-NEXT:    [[PERSPINTERPCENTER_I1:%.*]] = extractelement <2 x float> [[PERSPINTERPCENTER:%.*]], i64 1
+; ALL-NEXT:    [[PERSPINTERPCENTER_I0:%.*]] = extractelement <2 x float> [[PERSPINTERPCENTER]], i64 0
+; ALL-NEXT:    [[TMP0:%.*]] = call float @llvm.amdgcn.interp.p1(float [[PERSPINTERPCENTER_I0]], i32 immarg 1, i32 immarg 0, i32 [[PRIMMASK:%.*]])
+; ALL-NEXT:    [[TMP1:%.*]] = call float @llvm.amdgcn.interp.p2(float [[TMP0]], float [[PERSPINTERPCENTER_I1]], i32 immarg 1, i32 immarg 0, i32 [[PRIMMASK]])
+; ALL-NEXT:    [[TMP2:%.*]] = fmul reassoc nnan nsz arcp contract afn float [[TMP1]], 3.000000e+00
+; ALL-NEXT:    [[TMP3:%.*]] = call reassoc nnan nsz arcp contract afn float @llvm.floor.f32(float [[TMP2]])
+; ALL-NEXT:    [[TMP4:%.*]] = fptosi float [[TMP3]] to i32
+; ALL-NEXT:    [[DOTFR:%.*]] = freeze i32 [[TMP4]]
+; ALL-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[DOTFR]], 1
+; ALL-NEXT:    br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP12:%.*]]
+; ALL:       6:
+; ALL-NEXT:    [[TMP7:%.*]] = call float @llvm.amdgcn.interp.p1(float [[PERSPINTERPCENTER_I0]], i32 immarg 0, i32 immarg 0, i32 [[PRIMMASK]])
+; ALL-NEXT:    [[TMP8:%.*]] = call float @llvm.amdgcn.interp.p2(float [[TMP7]], float [[PERSPINTERPCENTER_I1]], i32 immarg 0, i32 immarg 0, i32 [[PRIMMASK]])
+; ALL-NEXT:    [[TMP9:%.*]] = fmul reassoc nnan nsz arcp contract afn float [[TMP8]], 4.000000e+00
+; ALL-NEXT:    [[TMP10:%.*]] = call reassoc nnan nsz arcp contract afn float @llvm.floor.f32(float [[TMP9]])
+; ALL-NEXT:    [[TMP11:%.*]] = fptosi float [[TMP10]] to i32
+; ALL-NEXT:    [[COND_FREEZE1:%.*]] = freeze i32 [[TMP11]]
+; ALL-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[COND_FREEZE1]], 1
+; ALL-NEXT:    [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], float 2.000000e+00, float 0.000000e+00
+; ALL-NEXT:    [[SWITCH_SELECTCMP1:%.*]] = icmp eq i32 [[COND_FREEZE1]], 0
+; ALL-NEXT:    [[SWITCH_SELECT2:%.*]] = select i1 [[SWITCH_SELECTCMP1]], float 1.000000e+00, float [[SWITCH_SELECT]]
+; ALL-NEXT:    br label [[TMP12]]
+; ALL:       12:
+; ALL-NEXT:    [[SAMPLEPOS_1_I0:%.*]] = phi float [ 0.000000e+00, [[DOTENTRY:%.*]] ], [ [[SWITCH_SELECT2]], [[TMP6]] ]
+; ALL-NEXT:    ret float [[SAMPLEPOS_1_I0]]
+;
+.entry:
+  %PerspInterpCenter.i1 = extractelement <2 x float> %PerspInterpCenter, i64 1
+  %PerspInterpCenter.i0 = extractelement <2 x float> %PerspInterpCenter, i64 0
+  %0 = call float @llvm.amdgcn.interp.p1(float %PerspInterpCenter.i0, i32 immarg 1, i32 immarg 0, i32 %PrimMask) #1
+  %1 = call float @llvm.amdgcn.interp.p2(float %0, float %PerspInterpCenter.i1, i32 immarg 1, i32 immarg 0, i32 %PrimMask) #1
+  %2 = fmul reassoc nnan nsz arcp contract afn float %1, 3.000000e00
+  %3 = call reassoc nnan nsz arcp contract afn float @llvm.floor.f32(float %2)
+  %4 = fptosi float %3 to i32
+  %.fr = freeze i32 %4
+  %5 = icmp eq i32 %.fr, 1
+  br i1 %5, label %6, label %14
+
+6:                                                ; preds = %.entry
+  %7 = call float @llvm.amdgcn.interp.p1(float %PerspInterpCenter.i0, i32 immarg 0, i32 immarg 0, i32 %PrimMask) #1
+  %8 = call float @llvm.amdgcn.interp.p2(float %7, float %PerspInterpCenter.i1, i32 immarg 0, i32 immarg 0, i32 %PrimMask) #1
+  %9 = fmul reassoc nnan nsz arcp contract afn float %8, 4.000000e00
+  %10 = call reassoc nnan nsz arcp contract afn float @llvm.floor.f32(float %9)
+  %11 = fptosi float %10 to i32
+  %cond.freeze1 = freeze i32 %11
+  switch i32 %cond.freeze1, label %14 [
+  i32 0, label %12
+  i32 1, label %13
+  ]
+
+12:                                               ; preds = %6
+  br label %14
+
+13:                                               ; preds = %6
+  br label %14
+
+14:                                               ; preds = %6, %12, %13, %.entry
+  %samplePos.1.i0 = phi float [ 0.000000e00, %.entry ], [ 0.000000e00, %6 ], [ 2.000000e00, %13 ], [ 1.000000e00, %12 ]
+  ret float %samplePos.1.i0
+}
+
+
+
+define float @SimpleTestSwitch(<2 x float> noundef %PerspInterpCenter, i32 inreg noundef %PrimMask) {
+; ALL-LABEL: @SimpleTestSwitch(
+; ALL-NEXT:  .entry:
+; ALL-NEXT:    [[PERSPINTERPCENTER_I1:%.*]] = extractelement <2 x float> [[PERSPINTERPCENTER:%.*]], i64 1
+; ALL-NEXT:    [[PERSPINTERPCENTER_I0:%.*]] = extractelement <2 x float> [[PERSPINTERPCENTER]], i64 0
+; ALL-NEXT:    [[TMP0:%.*]] = call float @llvm.amdgcn.interp.p1(float [[PERSPINTERPCENTER_I0]], i32 immarg 1, i32 immarg 0, i32 [[PRIMMASK:%.*]])
+; ALL-NEXT:    [[TMP1:%.*]] = call float @llvm.amdgcn.interp.p2(float [[TMP0]], float [[PERSPINTERPCENTER_I1]], i32 immarg 1, i32 immarg 0, i32 [[PRIMMASK]])
+; ALL-NEXT:    [[TMP2:%.*]] = fmul reassoc nnan nsz arcp contract afn float [[TMP1]], 3.000000e+00
+; ALL-NEXT:    [[TMP3:%.*]] = call reassoc nnan nsz arcp contract afn float @llvm.floor.f32(float [[TMP2]])
+; ALL-NEXT:    [[TMP4:%.*]] = fptosi float [[TMP3]] to i32
+; ALL-NEXT:    [[DOTFR:%.*]] = freeze i32 [[TMP4]]
+; ALL-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[DOTFR]], 1
+; ALL-NEXT:    br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP12:%.*]]
+; ALL:       6:
+; ALL-NEXT:    [[TMP7:%.*]] = call float @llvm.amdgcn.interp.p1(float [[PERSPINTERPCENTER_I0]], i32 immarg 0, i32 immarg 0, i32 [[PRIMMASK]])
+; ALL-NEXT:    [[TMP8:%.*]] = call float @llvm.amdgcn.interp.p2(float [[TMP7]], float [[PERSPINTERPCENTER_I1]], i32 immarg 0, i32 immarg 0, i32 [[PRIMMASK]])
+; ALL-NEXT:    [[TMP9:%.*]] = fmul reassoc nnan nsz arcp contract afn float [[TMP8]], 4.000000e+00
+; ALL-NEXT:    [[TMP10:%.*]] = call reassoc nnan nsz arcp contract afn float @llvm.floor.f32(float [[TMP9]])
+; ALL-NEXT:    [[TMP11:%.*]] = fptosi float [[TMP10]] to i32
+; ALL-NEXT:    [[COND_FREEZE1:%.*]] = freeze i32 [[TMP11]]
+; ALL-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[COND_FREEZE1]], 0
+; ALL-NEXT:    [[SWITCH_SELECTCMP1:%.*]] = icmp eq i32 [[COND_FREEZE1]], 1
+; ALL-NEXT:    [[SWITCH_SELECTCMP2:%.*]] = icmp eq i32 [[COND_FREEZE1]], 2
+; ALL-NEXT:    [[SWITCH_SELECTCMP3:%.*]] = icmp eq i32 [[COND_FREEZE1]], 3
+; ALL-NEXT:    [[SWITCHACIM_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP3]], float 4.000000e+00, float 0.000000e+00
+; ALL-NEXT:    [[SWITCHACIM_SELECT4:%.*]] = select i1 [[SWITCH_SELECTCMP2]], float 3.000000e+00, float [[SWITCHACIM_SELECT]]
+; ALL-NEXT:    [[SWITCHACIM_SELECT5:%.*]] = select i1 [[SWITCH_SELECTCMP1]], float 2.000000e+00, float [[SWITCHACIM_SELECT4]]
+; ALL-NEXT:    [[SWITCHACIM_SELECT6:%.*]] = select i1 [[SWITCH_SELECTCMP]], float 1.000000e+00, float [[SWITCHACIM_SELECT5]]
+; ALL-NEXT:    br label [[TMP12]]
+; ALL:       12:
+; ALL-NEXT:    [[SAMPLEPOS_1_I0:%.*]] = phi float [ 0.000000e+00, [[DOTENTRY:%.*]] ], [ [[SWITCHACIM_SELECT6]], [[TMP6]] ]
+; ALL-NEXT:    ret float [[SAMPLEPOS_1_I0]]
+;
+.entry:
+  %PerspInterpCenter.i1 = extractelement <2 x float> %PerspInterpCenter, i64 1
+  %PerspInterpCenter.i0 = extractelement <2 x float> %PerspInterpCenter, i64 0
+  %0 = call float @llvm.amdgcn.interp.p1(float %PerspInterpCenter.i0, i32 immarg 1, i32 immarg 0, i32 %PrimMask)...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/82795


More information about the llvm-commits mailing list