[PATCH] D50775: [InstCombine] Fix IC trying to create a xor of pointer types

Amara Emerson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 15 06:39:02 PDT 2018


aemerson created this revision.
aemerson added a reviewer: spatel.

[InstCombine] Fix IC trying to create a xor of pointer types.

We were previously crashing here because icmp operands can be pointers as well as integers, and the code didn't check before building a xor. I've fixed this by doing a ptrtoint convert on the assumption that ptrtoints are free.

rdar://42473741


Repository:
  rL LLVM

https://reviews.llvm.org/D50775

Files:
  lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  test/Transforms/InstCombine/xor-icmps.ll


Index: test/Transforms/InstCombine/xor-icmps.ll
===================================================================
--- test/Transforms/InstCombine/xor-icmps.ll
+++ test/Transforms/InstCombine/xor-icmps.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -instcombine -S | FileCheck %s
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
 
 define i1 @eq_zero(i4 %x, i4 %y) {
 ; CHECK-LABEL: @eq_zero(
@@ -158,3 +159,29 @@
   ret i1 %E
 }
 
+define i1 @xor_icmp_ptr(i8* %c, i8* %d) {
+; CHECK-LABEL: @xor_icmp_ptr(
+; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint i8* [[C:%.*]] to i64
+; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint i8* [[D:%.*]] to i64
+; CHECK-NEXT:    [[TMP3:%.*]] = xor i64 [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp slt i64 [[TMP3]], 0
+; CHECK-NEXT:    ret i1 [[TMP4]]
+;
+  %cmp = icmp slt i8* %c, null
+  %cmp1 = icmp slt i8* %d, null
+  %xor = xor i1 %cmp, %cmp1
+  ret i1 %xor
+}
+
+define i1 @xor_icmp_ptr_vec(<4 x i32>* %c, <4 x i32>* %d) {
+; CHECK-LABEL: @xor_icmp_ptr_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <4 x i32>* [[C:%.*]], null
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt <4 x i32>* [[D:%.*]], null
+; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[CMP]], [[CMP1]]
+; CHECK-NEXT:    ret i1 [[XOR]]
+;
+  %cmp = icmp slt <4 x i32>* %c, null
+  %cmp1 = icmp slt <4 x i32>* %d, null
+  %xor = xor i1 %cmp, %cmp1
+  ret i1 %xor
+}
Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2486,8 +2486,20 @@
   ICmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
   Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1);
   Value *RHS0 = RHS->getOperand(0), *RHS1 = RHS->getOperand(1);
+  PointerType *LHS0PtrTy = dyn_cast<PointerType>(LHS0->getType());
   if ((LHS->hasOneUse() || RHS->hasOneUse()) &&
-      LHS0->getType() == RHS0->getType()) {
+      LHS0->getType() == RHS0->getType() &&
+      !(LHS0PtrTy && LHS0PtrTy->getElementType()->isVectorTy())) {
+    if (!LHS0->getType()->isIntOrIntVectorTy()) {
+      assert(LHS0->getType()->isPointerTy() && RHS0->getType()->isPointerTy() &&
+             "expected ptrs");
+      Type *PtrIntTy = DL.getIntPtrType(LHS0->getType());
+      LHS0 = Builder.CreatePtrToInt(LHS0, PtrIntTy);
+      LHS1 = Builder.CreatePtrToInt(LHS1, PtrIntTy);
+      RHS0 = Builder.CreatePtrToInt(RHS0, PtrIntTy);
+      RHS1 = Builder.CreatePtrToInt(RHS1, PtrIntTy);
+    }
+
     // (X > -1) ^ (Y > -1) --> (X ^ Y) < 0
     // (X <  0) ^ (Y <  0) --> (X ^ Y) < 0
     if ((PredL == CmpInst::ICMP_SGT && match(LHS1, m_AllOnes()) &&


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50775.160792.patch
Type: text/x-patch
Size: 2776 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180815/275ca9f4/attachment.bin>


More information about the llvm-commits mailing list