[PATCH] D90231: [GVN] Don't replace argument to @llvm.is.constant.*()

Jonas Paulsson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 27 07:36:50 PDT 2020


jonpa created this revision.
jonpa added reviewers: Prazek, uweigand, reames.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.
jonpa requested review of this revision.

When building the Linux kernel with clang on SystemZ, the use of __builtin_constant_p() lead to the error "error: invalid operand for inline asm constraint 'i'". The purpose of this function is to do a compile-time check to see if the argument is constant or not. If it is not, then it should evaluate to false and the (in this case) inline asm statement should be removed.

GVN optimized a conditional branch controlled by a compare with zero. It deduced that in a specific block, the value must be zero since the branch must be taken to reach there. This lead to the non-constant argument (also the compared value) passed to __builtin_constant_p() being replaced with a zero in the successor block. This in turn resulted in the inline asm not being removed from the program and thus the error message of "i" being used incorrectly (there were multiple __builtin_constant_p calls in the program).

This patch suggest one way of handling this, namely by excluding the llvm.is.constant intrinsic from being optimized by GVN and similar passes...


https://reviews.llvm.org/D90231

Files:
  llvm/lib/Transforms/Utils/Local.cpp
  llvm/test/Transforms/GVN/is-constant.ll


Index: llvm/test/Transforms/GVN/is-constant.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/GVN/is-constant.ll
@@ -0,0 +1,30 @@
+; RUN: opt -gvn -S < %s | FileCheck %s
+;
+; Test that @llvm.is.constant() does not get its argument replaced with a
+; (runtime) constant.
+
+; CHECK-LABEL: define i32 @fun
+; CHECK: %2 = tail call i1 @llvm.is.constant.i32(i32 %shl)
+
+declare i1 @llvm.is.constant.i32(i32)
+
+ at a = global i32 0, align 4
+ at b = global i32 0, align 4
+
+define i32 @fun() {
+entry:
+  %0 = load i32, i32* @a
+  %shl = shl i32 %0, 12
+  store i32 %shl, i32* @b
+  %1 = icmp eq i32 %shl, 0
+  br i1 %1, label %land.rhs, label %land.end
+
+land.rhs:                                         ; preds = %entry
+  %2 = tail call i1 @llvm.is.constant.i32(i32 %shl)
+  %phi.cast = zext i1 %2 to i32
+  br label %land.end
+
+land.end:                                         ; preds = %land.rhs, %entry
+  %3 = phi i32 [ 0, %entry ], [ %phi.cast, %land.rhs ]
+  ret i32 %3
+}
Index: llvm/lib/Transforms/Utils/Local.cpp
===================================================================
--- llvm/lib/Transforms/Utils/Local.cpp
+++ llvm/lib/Transforms/Utils/Local.cpp
@@ -2604,6 +2604,13 @@
   combineMetadata(ReplInst, I, KnownIDs, false);
 }
 
+static bool exceptedFromValueReplacements(const User *U) {
+  if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U))
+    if (II->getIntrinsicID() == Intrinsic::is_constant)
+      return true;
+  return false;
+}
+
 template <typename RootType, typename DominatesFn>
 static unsigned replaceDominatedUsesWith(Value *From, Value *To,
                                          const RootType &Root,
@@ -2614,7 +2621,7 @@
   for (Value::use_iterator UI = From->use_begin(), UE = From->use_end();
        UI != UE;) {
     Use &U = *UI++;
-    if (!Dominates(Root, U))
+    if (!Dominates(Root, U) || exceptedFromValueReplacements(U.getUser()))
       continue;
     U.set(To);
     LLVM_DEBUG(dbgs() << "Replace dominated use of '" << From->getName()
@@ -2633,7 +2640,7 @@
        UI != UE;) {
     Use &U = *UI++;
     auto *I = cast<Instruction>(U.getUser());
-    if (I->getParent() == BB)
+    if (I->getParent() == BB || exceptedFromValueReplacements(I))
       continue;
     U.set(To);
     ++Count;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D90231.300982.patch
Type: text/x-patch
Size: 2317 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201027/8cf94d0f/attachment.bin>


More information about the llvm-commits mailing list