[llvm] r256126 - [X86] Prevent constant hoisting for a couple compare immediates that the selection DAG knows how to optimize into a shift.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 20 10:41:54 PST 2015


Author: ctopper
Date: Sun Dec 20 12:41:54 2015
New Revision: 256126

URL: http://llvm.org/viewvc/llvm-project?rev=256126&view=rev
Log:
[X86] Prevent constant hoisting for a couple compare immediates that the selection DAG knows how to optimize into a shift.

This allows "icmp ugt %a, 4294967295" and "icmp uge %a, 4294967296" to be optimized into right shifts by 32 which can fold the immediate into the shift instruction. These patterns show up with some regularity in real code.

Unfortunately, since getImmCost can't see the icmp predicate we can't be tell if we're only catching these specific cases.

Added:
    llvm/trunk/test/CodeGen/X86/constant-hoisting-cmp.ll
Modified:
    llvm/trunk/lib/Target/X86/X86TargetTransformInfo.cpp

Modified: llvm/trunk/lib/Target/X86/X86TargetTransformInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetTransformInfo.cpp?rev=256126&r1=256125&r2=256126&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86TargetTransformInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86TargetTransformInfo.cpp Sun Dec 20 12:41:54 2015
@@ -1199,6 +1199,19 @@ int X86TTIImpl::getIntImmCost(unsigned O
   case Instruction::Store:
     ImmIdx = 0;
     break;
+  case Instruction::ICmp:
+    // This is an imperfect hack to prevent constant hoisting of
+    // compares that might be trying to check if a 64-bit value fits in
+    // 32-bits. The backend can optimize these cases using a right shift by 32.
+    // Ideally we would check the compare predicate here. There also other
+    // similar immediates the backend can use shifts for.
+    if (Idx == 1 && Imm.getBitWidth() == 64) {
+      uint64_t ImmVal = Imm.getZExtValue();
+      if (ImmVal == 0x100000000ULL || ImmVal == 0xffffffff)
+        return TTI::TCC_Free;
+    }
+    ImmIdx = 1;
+    break;
   case Instruction::And:
     // We support 64-bit ANDs with immediates with 32-bits of leading zeroes
     // by using a 32-bit operation with implicit zero extension. Detect such
@@ -1215,7 +1228,6 @@ int X86TTIImpl::getIntImmCost(unsigned O
   case Instruction::SRem:
   case Instruction::Or:
   case Instruction::Xor:
-  case Instruction::ICmp:
     ImmIdx = 1;
     break;
   // Always return TCC_Free for the shift value of a shift instruction.

Added: llvm/trunk/test/CodeGen/X86/constant-hoisting-cmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/constant-hoisting-cmp.ll?rev=256126&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/constant-hoisting-cmp.ll (added)
+++ llvm/trunk/test/CodeGen/X86/constant-hoisting-cmp.ll Sun Dec 20 12:41:54 2015
@@ -0,0 +1,25 @@
+; RUN: llc < %s -O3 -march=x86-64 |FileCheck %s
+define i64 @foo(i64 %data1, i64 %data2, i64 %data3)
+{
+; If constant 4294967295 is hoisted to a variable, then we won't be able to
+; use a shift right by 32 to optimize the compare.
+entry:
+  %val1 = add i64 %data3, 1
+  %x = icmp ugt i64 %data1, 4294967295
+  br i1 %x, label %End, label %L_val2
+
+; CHECK: shrq    $32, {{.*}}
+; CHECK: shrq    $32, {{.*}}
+L_val2:
+  %val2 = add i64 %data3, 2
+  %y = icmp ugt i64 %data2, 4294967295
+  br i1 %y, label %End, label %L_val3
+
+L_val3:
+  %val3 = add i64 %data3, 3
+  br label %End
+
+End:
+  %p1 = phi i64 [%val1,%entry], [%val2,%L_val2], [%val3,%L_val3]
+  ret i64 %p1
+}




More information about the llvm-commits mailing list