[llvm] [Bitcode] Fix constexpr expansion creating invalid PHIs (PR #141560)

Timothy Werquin via llvm-commits llvm-commits at lists.llvm.org
Tue May 27 05:34:04 PDT 2025


https://github.com/timower updated https://github.com/llvm/llvm-project/pull/141560

>From 08da89a4d28d1bcbd4b551f7c22e853ac1174dad Mon Sep 17 00:00:00 2001
From: Timothy Werquin <timothy.werquin at guardsquare.com>
Date: Tue, 27 May 2025 14:33:29 +0200
Subject: [PATCH] [Bitcode] Fix constexpr expansion creating invalid PHIs

Fixes errors about duplicate PHI edges when the input had duplicates with
constexprs in them. The constexpr translation makes new basic blocks,
causing the verifier to complain about duplicate entries in PHI nodes.
---
 llvm/lib/Bitcode/Reader/BitcodeReader.cpp     |   8 +++--
 llvm/test/Bitcode/constexpr-to-instr-dups.ll  |  30 ++++++++++++++++++
 .../Bitcode/constexpr-to-instr-dups.ll.bc     | Bin 0 -> 1436 bytes
 llvm/test/Bitcode/constexpr-to-instr.ll       |   4 +--
 4 files changed, 38 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/Bitcode/constexpr-to-instr-dups.ll
 create mode 100644 llvm/test/Bitcode/constexpr-to-instr-dups.ll.bc

diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 58625ee49c8ad..ce7b1ef65eed7 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -6095,14 +6095,18 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
         // seen value here, to avoid expanding a constant expression multiple
         // times.
         auto It = Args.find(BB);
+        BasicBlock *EdgeBB = ConstExprEdgeBBs.lookup({BB, CurBB});
         if (It != Args.end()) {
-          PN->addIncoming(It->second, BB);
+          // If this predecessor was also replaced with a constexpr basic
+          // block, it must be de-duplicated.
+          if (!EdgeBB) {
+            PN->addIncoming(It->second, BB);
+          }
           continue;
         }
 
         // If there already is a block for this edge (from a different phi),
         // use it.
-        BasicBlock *EdgeBB = ConstExprEdgeBBs.lookup({BB, CurBB});
         if (!EdgeBB) {
           // Otherwise, use a temporary block (that we will discard if it
           // turns out to be unnecessary).
diff --git a/llvm/test/Bitcode/constexpr-to-instr-dups.ll b/llvm/test/Bitcode/constexpr-to-instr-dups.ll
new file mode 100644
index 0000000000000..dee9490b616fa
--- /dev/null
+++ b/llvm/test/Bitcode/constexpr-to-instr-dups.ll
@@ -0,0 +1,30 @@
+; RUN: opt -expand-constant-exprs %s.bc -S | FileCheck %s
+ at foo = external constant i32
+
+define i32 @test(i32 %arg) {
+entry:
+  switch i32 %arg, label %cont [
+    i32 1, label %cont
+    i32 2, label %nonconst
+  ]
+
+nonconst:
+  %cmp = icmp ne i32 %arg, 2
+  br i1 %cmp, label %cont, label %cont
+
+; CHECK-LABEL: phi.constexpr:
+; CHECK-NEXT:    %constexpr = ptrtoint ptr @foo to i32
+; CHECK-NEXT:    %constexpr1 = or i32 %constexpr, 5
+; CHECK-NEXT:    br label %cont
+
+
+; CHECK-LABEL: cont:
+; CHECK-NEXT:    %res = phi i32 [ %constexpr1, %phi.constexpr ], [ 1, %nonconst ], [ 1, %nonconst ]
+; CHECK-NEXT:    ret i32 %res
+cont:
+  %res = phi i32 [or (i32 5, i32 ptrtoint (ptr @foo to i32)), %entry],
+                 [or (i32 5, i32 ptrtoint (ptr @foo to i32)), %entry],
+                 [1, %nonconst],
+                 [1, %nonconst]
+  ret i32 %res
+}
diff --git a/llvm/test/Bitcode/constexpr-to-instr-dups.ll.bc b/llvm/test/Bitcode/constexpr-to-instr-dups.ll.bc
new file mode 100644
index 0000000000000000000000000000000000000000..7897f51322fcc3e9ce738c66fc90d36dde5c1fb1
GIT binary patch
literal 1436
zcmXw3e{2&~9Dmo_c4aH?%BaxEUA?0d8-jTKv8~6o$<{+t0Z9S>m<fip%m$P|x7Gau
zO-qM2Vol1@#A-0v68 at 0CEM|XTG7arbEVIHyW0trqt?OWzf(uMSB7gY3p)YygckkuB
z at B4f|pU*p=d~Kn{gitL)C}a?t_q_F8_}hObziK!T+eg3}Z$QWo9}PMl>0rJIIu*BG
z=qS{@UT1WOW5kHz#aexnrRL*M%<!ttH`d_mHabjhy?JlF!!hcQO!L;=jY`tkF{bM-
z=&zVK`L$8*2H|jwn77-ur|f64hc9qy0rH;b5Q6K_)^LsSYv0)$#)A-2J^6sYe%&_t
zdaci~O^-jfqQur_k~oB{sINwYi1yI>4P)&eCDVv-`OJ?q`r{8jJ%>mN87|lPv<?3^
zH#)ywckVN&BV>oQZ=gH%F=o2VgiVBZRCbT3NneZ_8l?I%J%&4ozHh{<G3+$>EcqOJ
zbAkyAwQJiFTZ*K&AbXRfw>X%LMyS(zYRIodBGhn%>>pGjoYGX>fU7B77U+`#y|{u`
z0@!JsW*2y7j%V{hOISEBO(mpRS)3$2Qwh%qDHT^t{aw`QV^rHQr59pMiKLWB7u9d0
z`k&N7+JTsIM6dLimEMdpl!@<nu!0|y at ZZ;PRUku!38pf^6xZT>keT6`={P$Rtotn`
ziv?NCti`LUJ1x6MNhz(q0+&8LEB#7JS=I2vaV65J^hOfVW7J at m5;ZH)ai!_zA^HKL
z9|mwGg%{iDGKZ^B1!rUDbC!IE<u=dE$1U?Erc!4ABrIX`0e4p3bul3o1I_;x(xnUx
zQiGWT`&Lu5#(?Er%S at 12=GlcD`ypY`0Q2lhu<p%s33pMIva%Nld7AfBWN8$pYV!Mf
zs8ksMJbG%_M)hXmhZl{wdJQiH at FT&RyWL at _lsC_n*#!XLZ<4YJ?_^@ji0V$tVo~*6
z&4~pSYV;KSlRbJ0Q1t+Tol4X1*KxIrzF(?a;pioSUgGG-0esSk7X=K{N2R)ZC0q&M
zCxZ2lYLLmt*}3xOD$m~G*=e2y1(*33!rT|ql<d7qis^({?3 at Diq1a)-=~o6KO4E;b
z at m~U6F5!Fa^u2MoMJ33-FDa<yNCvE;F&v!*DdQs at Vo3$+yr5LEeR`aonP5vDmW3P>
zZaymDvZgN$NtOhePrPrY`uxg~apg=5&R$6qo}}tYtL|BO7ucx?j2Zm=bH1Pjpx(@}
z2jeDm*^JQ3;Pr<3UK at Cb8t#l_0JnCfIIEt$!(5+Ozuci&9L_w`W|M2N3*QZZ<a9+7
zp1vEvtJzqb8nUf9a!>&_H9a~b7ghHpAzey%)2i-0FgG(_X68Aj64c^y+>#G6vlC3=
z8HvFhL9cRjIY7g^Y8ZW1OzkZ<K%WDHsz9X#%E7xTkdpRne>Ngi2P0MVTuMk6!MLP%
zJmCQor&R6n2RVeEhjC+#yaTqP8tCapn{F>k=WXgis2m}ciSq{C21A>9x4G!h`-DKF
z5fK8h at q`g;``1C=CZG$!b at FciOYQpo&Zayk+^Xe1`9;6q`UVv+{$vVjiJ<jx2$3*4
zuyN}Mk=1^QYwd0LaczXJMl$_ at wh%sbD*8 at e)ZVsJ*xAZC?X9BNVs|-PyIWdA-GV#R
gX1BXqT3v#8)NXgWT&`A^7-|!>BRfx=Sj&jeznPuq-v9sr

literal 0
HcmV?d00001

diff --git a/llvm/test/Bitcode/constexpr-to-instr.ll b/llvm/test/Bitcode/constexpr-to-instr.ll
index c099273de810f..c6c0f449ef29d 100644
--- a/llvm/test/Bitcode/constexpr-to-instr.ll
+++ b/llvm/test/Bitcode/constexpr-to-instr.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-dis -expand-constant-exprs < %s.bc | FileCheck %s
+; RUN: opt -expand-constant-exprs -S %s.bc | FileCheck %s
 
 @g = extern_weak global i32
 @g2 = extern_weak global i32
@@ -225,7 +225,7 @@ define i64 @test_phi_multiple_identical_predecessors(i32 %x) {
 ; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
 ; CHECK-NEXT: br label %join
 ; CHECK: join:
-; CHECK-NEXT: %phi = phi i64 [ %constexpr, %phi.constexpr ], [ %constexpr, %phi.constexpr ], [ 0, %default ]
+; CHECK-NEXT: %phi = phi i64 [ %constexpr, %phi.constexpr ], [ 0, %default ]
 ; CHECK-NEXT: ret i64 %phi
 entry:
   switch i32 %x, label %default [



More information about the llvm-commits mailing list