ymandel updated this revision to Diff 266190.
ymandel marked an inline comment as done.
ymandel added a comment.
Herald added subscribers: llvm-commits, dmgreen.
Herald added a project: LLVM.

adds fixme comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80239/new/

https://reviews.llvm.org/D80239

Files:
  clang/lib/Tooling/Transformer/Transformer.cpp
  clang/unittests/Tooling/TransformerTest.cpp
  llvm/test/CodeGen/Thumb2/mve-vmaxv.ll

Index: llvm/test/CodeGen/Thumb2/mve-vmaxv.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/mve-vmaxv.ll
+++ llvm/test/CodeGen/Thumb2/mve-vmaxv.ll
@@ -14,8 +14,8 @@
 declare i16 @llvm.experimental.vector.reduce.umin.v8i16(<8 x i16>)
 declare i32 @llvm.experimental.vector.reduce.umin.v4i32(<4 x i32>)
 
-define arm_aapcs_vfpcc i8 @vmaxv_s_v16i8_i32(<16 x i8> %s1) {
-; CHECK-LABEL: vmaxv_s_v16i8_i32:
+define arm_aapcs_vfpcc i8 @vmaxv_s_v16i8(<16 x i8> %s1) {
+; CHECK-LABEL: vmaxv_s_v16i8:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    mvn r0, #127
 ; CHECK-NEXT:    vmaxv.s8 r0, q0
@@ -24,8 +24,8 @@
   ret i8 %r
 }
 
-define arm_aapcs_vfpcc i16 @vmaxv_s_v8i16_i32(<8 x i16> %s1) {
-; CHECK-LABEL: vmaxv_s_v8i16_i32:
+define arm_aapcs_vfpcc i16 @vmaxv_s_v8i16(<8 x i16> %s1) {
+; CHECK-LABEL: vmaxv_s_v8i16:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    movw r0, #32768
 ; CHECK-NEXT:    movt r0, #65535
@@ -35,8 +35,8 @@
   ret i16 %r
 }
 
-define arm_aapcs_vfpcc i32 @vmaxv_s_v4i32_i32(<4 x i32> %s1) {
-; CHECK-LABEL: vmaxv_s_v4i32_i32:
+define arm_aapcs_vfpcc i32 @vmaxv_s_v4i32(<4 x i32> %s1) {
+; CHECK-LABEL: vmaxv_s_v4i32:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    mov.w r0, #-2147483648
 ; CHECK-NEXT:    vmaxv.s32 r0, q0
@@ -45,8 +45,8 @@
   ret i32 %r
 }
 
-define arm_aapcs_vfpcc i8 @vmaxv_u_v16i8_i32(<16 x i8> %s1) {
-; CHECK-LABEL: vmaxv_u_v16i8_i32:
+define arm_aapcs_vfpcc i8 @vmaxv_u_v16i8(<16 x i8> %s1) {
+; CHECK-LABEL: vmaxv_u_v16i8:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    movs r0, #0
 ; CHECK-NEXT:    vmaxv.u8 r0, q0
@@ -55,8 +55,8 @@
   ret i8 %r
 }
 
-define arm_aapcs_vfpcc i16 @vmaxv_u_v8i16_i32(<8 x i16> %s1) {
-; CHECK-LABEL: vmaxv_u_v8i16_i32:
+define arm_aapcs_vfpcc i16 @vmaxv_u_v8i16(<8 x i16> %s1) {
+; CHECK-LABEL: vmaxv_u_v8i16:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    movs r0, #0
 ; CHECK-NEXT:    vmaxv.u16 r0, q0
@@ -65,8 +65,8 @@
   ret i16 %r
 }
 
-define arm_aapcs_vfpcc i32 @vmaxv_u_v4i32_i32(<4 x i32> %s1) {
-; CHECK-LABEL: vmaxv_u_v4i32_i32:
+define arm_aapcs_vfpcc i32 @vmaxv_u_v4i32(<4 x i32> %s1) {
+; CHECK-LABEL: vmaxv_u_v4i32:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    movs r0, #0
 ; CHECK-NEXT:    vmaxv.u32 r0, q0
@@ -75,8 +75,8 @@
   ret i32 %r
 }
 
-define arm_aapcs_vfpcc i8 @vminv_s_v16i8_i32(<16 x i8> %s1) {
-; CHECK-LABEL: vminv_s_v16i8_i32:
+define arm_aapcs_vfpcc i8 @vminv_s_v16i8(<16 x i8> %s1) {
+; CHECK-LABEL: vminv_s_v16i8:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    movs r0, #127
 ; CHECK-NEXT:    vminv.s8 r0, q0
@@ -85,8 +85,8 @@
   ret i8 %r
 }
 
-define arm_aapcs_vfpcc i16 @vminv_s_v8i16_i32(<8 x i16> %s1) {
-; CHECK-LABEL: vminv_s_v8i16_i32:
+define arm_aapcs_vfpcc i16 @vminv_s_v8i16(<8 x i16> %s1) {
+; CHECK-LABEL: vminv_s_v8i16:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    movw r0, #32767
 ; CHECK-NEXT:    vminv.s16 r0, q0
@@ -95,8 +95,8 @@
   ret i16 %r
 }
 
-define arm_aapcs_vfpcc i32 @vminv_s_v4i32_i32(<4 x i32> %s1) {
-; CHECK-LABEL: vminv_s_v4i32_i32:
+define arm_aapcs_vfpcc i32 @vminv_s_v4i32(<4 x i32> %s1) {
+; CHECK-LABEL: vminv_s_v4i32:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    mvn r0, #-2147483648
 ; CHECK-NEXT:    vminv.s32 r0, q0
@@ -105,8 +105,8 @@
   ret i32 %r
 }
 
-define arm_aapcs_vfpcc i8 @vminv_u_v16i8_i32(<16 x i8> %s1) {
-; CHECK-LABEL: vminv_u_v16i8_i32:
+define arm_aapcs_vfpcc i8 @vminv_u_v16i8(<16 x i8> %s1) {
+; CHECK-LABEL: vminv_u_v16i8:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    movs r0, #255
 ; CHECK-NEXT:    vminv.u8 r0, q0
@@ -115,8 +115,8 @@
   ret i8 %r
 }
 
-define arm_aapcs_vfpcc i16 @vminv_u_v8i16_i32(<8 x i16> %s1) {
-; CHECK-LABEL: vminv_u_v8i16_i32:
+define arm_aapcs_vfpcc i16 @vminv_u_v8i16(<8 x i16> %s1) {
+; CHECK-LABEL: vminv_u_v8i16:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    movw r0, #65535
 ; CHECK-NEXT:    vminv.u16 r0, q0
@@ -125,8 +125,8 @@
   ret i16 %r
 }
 
-define arm_aapcs_vfpcc i32 @vminv_u_v4i32_i32(<4 x i32> %s1) {
-; CHECK-LABEL: vminv_u_v4i32_i32:
+define arm_aapcs_vfpcc i32 @vminv_u_v4i32(<4 x i32> %s1) {
+; CHECK-LABEL: vminv_u_v4i32:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    mov.w r0, #-1
 ; CHECK-NEXT:    vminv.u32 r0, q0
@@ -134,3 +134,339 @@
   %r = call i32 @llvm.experimental.vector.reduce.umin.v4i32(<4 x i32> %s1)
   ret i32 %r
 }
+
+
+
+define arm_aapcs_vfpcc i8 @vmaxv_s_v16i8_i8(<16 x i8> %s1, i8 %s2) {
+; CHECK-LABEL: vmaxv_s_v16i8_i8:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    mvn r1, #127
+; CHECK-NEXT:    sxtb r3, r0
+; CHECK-NEXT:    vmaxv.s8 r1, q0
+; CHECK-NEXT:    sxtb r2, r1
+; CHECK-NEXT:    cmp r2, r3
+; CHECK-NEXT:    it gt
+; CHECK-NEXT:    movgt r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i8 @llvm.experimental.vector.reduce.smax.v16i8(<16 x i8> %s1)
+  %c = icmp sgt i8 %r, %s2
+  %s = select i1 %c, i8 %r, i8 %s2
+  ret i8 %s
+}
+
+define arm_aapcs_vfpcc i32 @vmaxv_s_v16i8_i32(<16 x i8> %s1, i32 %s2) {
+; CHECK-LABEL: vmaxv_s_v16i8_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    mvn r1, #127
+; CHECK-NEXT:    vmaxv.s8 r1, q0
+; CHECK-NEXT:    sxtb r1, r1
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it gt
+; CHECK-NEXT:    movgt r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i8 @llvm.experimental.vector.reduce.smax.v16i8(<16 x i8> %s1)
+  %rs = sext i8 %r to i32
+  %c = icmp sgt i32 %rs, %s2
+  %s = select i1 %c, i32 %rs, i32 %s2
+  ret i32 %s
+}
+
+define arm_aapcs_vfpcc i16 @vmaxv_s_v8i16_i16(<8 x i16> %s1, i16 %s2) {
+; CHECK-LABEL: vmaxv_s_v8i16_i16:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movw r1, #32768
+; CHECK-NEXT:    sxth r3, r0
+; CHECK-NEXT:    movt r1, #65535
+; CHECK-NEXT:    vmaxv.s16 r1, q0
+; CHECK-NEXT:    sxth r2, r1
+; CHECK-NEXT:    cmp r2, r3
+; CHECK-NEXT:    it gt
+; CHECK-NEXT:    movgt r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i16 @llvm.experimental.vector.reduce.smax.v8i16(<8 x i16> %s1)
+  %c = icmp sgt i16 %r, %s2
+  %s = select i1 %c, i16 %r, i16 %s2
+  ret i16 %s
+}
+
+define arm_aapcs_vfpcc i32 @vmaxv_s_v8i16_i32(<8 x i16> %s1, i32 %s2) {
+; CHECK-LABEL: vmaxv_s_v8i16_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movw r1, #32768
+; CHECK-NEXT:    movt r1, #65535
+; CHECK-NEXT:    vmaxv.s16 r1, q0
+; CHECK-NEXT:    sxth r1, r1
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it gt
+; CHECK-NEXT:    movgt r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i16 @llvm.experimental.vector.reduce.smax.v8i16(<8 x i16> %s1)
+  %rs = sext i16 %r to i32
+  %c = icmp sgt i32 %rs, %s2
+  %s = select i1 %c, i32 %rs, i32 %s2
+  ret i32 %s
+}
+
+define arm_aapcs_vfpcc i32 @vmaxv_s_v4i32_i32(<4 x i32> %s1, i32 %s2) {
+; CHECK-LABEL: vmaxv_s_v4i32_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    mov.w r1, #-2147483648
+; CHECK-NEXT:    vmaxv.s32 r1, q0
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it gt
+; CHECK-NEXT:    movgt r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i32 @llvm.experimental.vector.reduce.smax.v4i32(<4 x i32> %s1)
+  %c = icmp sgt i32 %r, %s2
+  %s = select i1 %c, i32 %r, i32 %s2
+  ret i32 %s
+}
+
+define arm_aapcs_vfpcc i8 @vmaxv_u_v16i8_i8(<16 x i8> %s1, i8 %s2) {
+; CHECK-LABEL: vmaxv_u_v16i8_i8:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #0
+; CHECK-NEXT:    uxtb r3, r0
+; CHECK-NEXT:    vmaxv.u8 r1, q0
+; CHECK-NEXT:    uxtb r2, r1
+; CHECK-NEXT:    cmp r2, r3
+; CHECK-NEXT:    it hi
+; CHECK-NEXT:    movhi r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i8 @llvm.experimental.vector.reduce.umax.v16i8(<16 x i8> %s1)
+  %c = icmp ugt i8 %r, %s2
+  %s = select i1 %c, i8 %r, i8 %s2
+  ret i8 %s
+}
+
+define arm_aapcs_vfpcc i32 @vmaxv_u_v16i8_i32(<16 x i8> %s1, i32 %s2) {
+; CHECK-LABEL: vmaxv_u_v16i8_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #0
+; CHECK-NEXT:    vmaxv.u8 r1, q0
+; CHECK-NEXT:    uxtb r1, r1
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it hi
+; CHECK-NEXT:    movhi r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i8 @llvm.experimental.vector.reduce.umax.v16i8(<16 x i8> %s1)
+  %rs = zext i8 %r to i32
+  %c = icmp ugt i32 %rs, %s2
+  %s = select i1 %c, i32 %rs, i32 %s2
+  ret i32 %s
+}
+
+define arm_aapcs_vfpcc i16 @vmaxv_u_v8i16_i16(<8 x i16> %s1, i16 %s2) {
+; CHECK-LABEL: vmaxv_u_v8i16_i16:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #0
+; CHECK-NEXT:    uxth r3, r0
+; CHECK-NEXT:    vmaxv.u16 r1, q0
+; CHECK-NEXT:    uxth r2, r1
+; CHECK-NEXT:    cmp r2, r3
+; CHECK-NEXT:    it hi
+; CHECK-NEXT:    movhi r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i16 @llvm.experimental.vector.reduce.umax.v8i16(<8 x i16> %s1)
+  %c = icmp ugt i16 %r, %s2
+  %s = select i1 %c, i16 %r, i16 %s2
+  ret i16 %s
+}
+
+define arm_aapcs_vfpcc i32 @vmaxv_u_v8i16_i32(<8 x i16> %s1, i32 %s2) {
+; CHECK-LABEL: vmaxv_u_v8i16_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #0
+; CHECK-NEXT:    vmaxv.u16 r1, q0
+; CHECK-NEXT:    uxth r1, r1
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it hi
+; CHECK-NEXT:    movhi r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i16 @llvm.experimental.vector.reduce.umax.v8i16(<8 x i16> %s1)
+  %rs = zext i16 %r to i32
+  %c = icmp ugt i32 %rs, %s2
+  %s = select i1 %c, i32 %rs, i32 %s2
+  ret i32 %s
+}
+
+define arm_aapcs_vfpcc i32 @vmaxv_u_v4i32_i32(<4 x i32> %s1, i32 %s2) {
+; CHECK-LABEL: vmaxv_u_v4i32_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #0
+; CHECK-NEXT:    vmaxv.u32 r1, q0
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it hi
+; CHECK-NEXT:    movhi r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i32 @llvm.experimental.vector.reduce.umax.v4i32(<4 x i32> %s1)
+  %c = icmp ugt i32 %r, %s2
+  %s = select i1 %c, i32 %r, i32 %s2
+  ret i32 %s
+}
+
+define arm_aapcs_vfpcc i8 @vminv_s_v16i8_i8(<16 x i8> %s1, i8 %s2) {
+; CHECK-LABEL: vminv_s_v16i8_i8:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #127
+; CHECK-NEXT:    sxtb r3, r0
+; CHECK-NEXT:    vminv.s8 r1, q0
+; CHECK-NEXT:    sxtb r2, r1
+; CHECK-NEXT:    cmp r2, r3
+; CHECK-NEXT:    it lt
+; CHECK-NEXT:    movlt r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i8 @llvm.experimental.vector.reduce.smin.v16i8(<16 x i8> %s1)
+  %c = icmp slt i8 %r, %s2
+  %s = select i1 %c, i8 %r, i8 %s2
+  ret i8 %s
+}
+
+define arm_aapcs_vfpcc i32 @vminv_s_v16i8_i32(<16 x i8> %s1, i32 %s2) {
+; CHECK-LABEL: vminv_s_v16i8_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #127
+; CHECK-NEXT:    vminv.s8 r1, q0
+; CHECK-NEXT:    sxtb r1, r1
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it lt
+; CHECK-NEXT:    movlt r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i8 @llvm.experimental.vector.reduce.smin.v16i8(<16 x i8> %s1)
+  %rs = sext i8 %r to i32
+  %c = icmp slt i32 %rs, %s2
+  %s = select i1 %c, i32 %rs, i32 %s2
+  ret i32 %s
+}
+
+define arm_aapcs_vfpcc i16 @vminv_s_v8i16_i16(<8 x i16> %s1, i16 %s2) {
+; CHECK-LABEL: vminv_s_v8i16_i16:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movw r1, #32767
+; CHECK-NEXT:    sxth r3, r0
+; CHECK-NEXT:    vminv.s16 r1, q0
+; CHECK-NEXT:    sxth r2, r1
+; CHECK-NEXT:    cmp r2, r3
+; CHECK-NEXT:    it lt
+; CHECK-NEXT:    movlt r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i16 @llvm.experimental.vector.reduce.smin.v8i16(<8 x i16> %s1)
+  %c = icmp slt i16 %r, %s2
+  %s = select i1 %c, i16 %r, i16 %s2
+  ret i16 %s
+}
+
+define arm_aapcs_vfpcc i32 @vminv_s_v8i16_i32(<8 x i16> %s1, i32 %s2) {
+; CHECK-LABEL: vminv_s_v8i16_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movw r1, #32767
+; CHECK-NEXT:    vminv.s16 r1, q0
+; CHECK-NEXT:    sxth r1, r1
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it lt
+; CHECK-NEXT:    movlt r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i16 @llvm.experimental.vector.reduce.smin.v8i16(<8 x i16> %s1)
+  %rs = sext i16 %r to i32
+  %c = icmp slt i32 %rs, %s2
+  %s = select i1 %c, i32 %rs, i32 %s2
+  ret i32 %s
+}
+
+define arm_aapcs_vfpcc i32 @vminv_s_v4i32_i32(<4 x i32> %s1, i32 %s2) {
+; CHECK-LABEL: vminv_s_v4i32_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    mvn r1, #-2147483648
+; CHECK-NEXT:    vminv.s32 r1, q0
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it lt
+; CHECK-NEXT:    movlt r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i32 @llvm.experimental.vector.reduce.smin.v4i32(<4 x i32> %s1)
+  %c = icmp slt i32 %r, %s2
+  %s = select i1 %c, i32 %r, i32 %s2
+  ret i32 %s
+}
+
+define arm_aapcs_vfpcc i8 @vminv_u_v16i8_i8(<16 x i8> %s1, i8 %s2) {
+; CHECK-LABEL: vminv_u_v16i8_i8:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #255
+; CHECK-NEXT:    uxtb r3, r0
+; CHECK-NEXT:    vminv.u8 r1, q0
+; CHECK-NEXT:    uxtb r2, r1
+; CHECK-NEXT:    cmp r2, r3
+; CHECK-NEXT:    it lo
+; CHECK-NEXT:    movlo r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i8 @llvm.experimental.vector.reduce.umin.v16i8(<16 x i8> %s1)
+  %c = icmp ult i8 %r, %s2
+  %s = select i1 %c, i8 %r, i8 %s2
+  ret i8 %s
+}
+
+define arm_aapcs_vfpcc i32 @vminv_u_v16i8_i32(<16 x i8> %s1, i32 %s2) {
+; CHECK-LABEL: vminv_u_v16i8_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movs r1, #255
+; CHECK-NEXT:    vminv.u8 r1, q0
+; CHECK-NEXT:    uxtb r1, r1
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it lo
+; CHECK-NEXT:    movlo r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i8 @llvm.experimental.vector.reduce.umin.v16i8(<16 x i8> %s1)
+  %rs = zext i8 %r to i32
+  %c = icmp ult i32 %rs, %s2
+  %s = select i1 %c, i32 %rs, i32 %s2
+  ret i32 %s
+}
+
+define arm_aapcs_vfpcc i16 @vminv_u_v8i16_i16(<8 x i16> %s1, i16 %s2) {
+; CHECK-LABEL: vminv_u_v8i16_i16:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movw r1, #65535
+; CHECK-NEXT:    uxth r3, r0
+; CHECK-NEXT:    vminv.u16 r1, q0
+; CHECK-NEXT:    uxth r2, r1
+; CHECK-NEXT:    cmp r2, r3
+; CHECK-NEXT:    it lo
+; CHECK-NEXT:    movlo r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i16 @llvm.experimental.vector.reduce.umin.v8i16(<8 x i16> %s1)
+  %c = icmp ult i16 %r, %s2
+  %s = select i1 %c, i16 %r, i16 %s2
+  ret i16 %s
+}
+
+define arm_aapcs_vfpcc i32 @vminv_u_v8i16_i32(<8 x i16> %s1, i32 %s2) {
+; CHECK-LABEL: vminv_u_v8i16_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    movw r1, #65535
+; CHECK-NEXT:    vminv.u16 r1, q0
+; CHECK-NEXT:    uxth r1, r1
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it lo
+; CHECK-NEXT:    movlo r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i16 @llvm.experimental.vector.reduce.umin.v8i16(<8 x i16> %s1)
+  %rs = zext i16 %r to i32
+  %c = icmp ult i32 %rs, %s2
+  %s = select i1 %c, i32 %rs, i32 %s2
+  ret i32 %s
+}
+
+define arm_aapcs_vfpcc i32 @vminv_u_v4i32_i32(<4 x i32> %s1, i32 %s2) {
+; CHECK-LABEL: vminv_u_v4i32_i32:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    mov.w r1, #-1
+; CHECK-NEXT:    vminv.u32 r1, q0
+; CHECK-NEXT:    cmp r1, r0
+; CHECK-NEXT:    it lo
+; CHECK-NEXT:    movlo r0, r1
+; CHECK-NEXT:    bx lr
+  %r = call i32 @llvm.experimental.vector.reduce.umin.v4i32(<4 x i32> %s1)
+  %c = icmp ult i32 %r, %s2
+  %s = select i1 %c, i32 %r, i32 %s2
+  ret i32 %s
+}
Index: clang/unittests/Tooling/TransformerTest.cpp
===================================================================
--- clang/unittests/Tooling/TransformerTest.cpp
+++ clang/unittests/Tooling/TransformerTest.cpp
@@ -817,4 +817,46 @@
                "Matcher must be.*node matcher");
 }
 #endif
+
+// Edits are able to span multiple files; in this case, a header and an
+// implementation file.
+TEST_F(TransformerTest, MultipleFiles) {
+  std::string Header = R"cc(void RemoveThisFunction();)cc";
+  std::string Source = R"cc(#include "input.h"
+                            void RemoveThisFunction();)cc";
+  Transformer T(
+      makeRule(functionDecl(hasName("RemoveThisFunction")), changeTo(cat(""))),
+      consumer());
+  T.registerMatchers(&MatchFinder);
+  auto Factory = newFrontendActionFactory(&MatchFinder);
+  EXPECT_TRUE(runToolOnCodeWithArgs(
+      Factory->create(), Source, std::vector<std::string>(), "input.cc",
+      "clang-tool", std::make_shared<PCHContainerOperations>(),
+      {{"input.h", Header}}));
+
+  std::sort(Changes.begin(), Changes.end(),
+            [](const AtomicChange &L, const AtomicChange &R) {
+              return L.getFilePath() < R.getFilePath();
+            });
+
+  ASSERT_EQ(Changes[0].getFilePath(), "./input.h");
+  EXPECT_THAT(Changes[0].getInsertedHeaders(), IsEmpty());
+  EXPECT_THAT(Changes[0].getRemovedHeaders(), IsEmpty());
+  llvm::Expected<std::string> UpdatedCode =
+      clang::tooling::applyAllReplacements(Header,
+                                           Changes[0].getReplacements());
+  ASSERT_TRUE(static_cast<bool>(UpdatedCode))
+      << "Could not update code: " << llvm::toString(UpdatedCode.takeError());
+  EXPECT_EQ(format(*UpdatedCode), format(R"cc(;)cc"));
+
+  ASSERT_EQ(Changes[1].getFilePath(), "input.cc");
+  EXPECT_THAT(Changes[1].getInsertedHeaders(), IsEmpty());
+  EXPECT_THAT(Changes[1].getRemovedHeaders(), IsEmpty());
+  UpdatedCode = clang::tooling::applyAllReplacements(
+      Source, Changes[1].getReplacements());
+  ASSERT_TRUE(static_cast<bool>(UpdatedCode))
+      << "Could not update code: " << llvm::toString(UpdatedCode.takeError());
+  EXPECT_EQ(format(*UpdatedCode), format(R"cc(#include "input.h"
+                        ;)cc"));
+}
 } // namespace
Index: clang/lib/Tooling/Transformer/Transformer.cpp
===================================================================
--- clang/lib/Tooling/Transformer/Transformer.cpp
+++ clang/lib/Tooling/Transformer/Transformer.cpp
@@ -12,6 +12,7 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Tooling/Refactoring/AtomicChange.h"
 #include "llvm/Support/Error.h"
+#include <map>
 #include <utility>
 #include <vector>
 
@@ -45,28 +46,39 @@
     return;
   }
 
-  // Record the results in the AtomicChange, anchored at the location of the
-  // first change.
-  AtomicChange AC(*Result.SourceManager,
-                  (*Transformations)[0].Range.getBegin());
+  // Group the transformations, by file, into AtomicChanges, each anchored by
+  // the location of the first change in that file.
+  std::map<FileID, AtomicChange> ChangesByFileID;
   for (const auto &T : *Transformations) {
+    auto ID = Result.SourceManager->getFileID(T.Range.getBegin());
+    auto Iter = ChangesByFileID
+                    .emplace(ID, AtomicChange(*Result.SourceManager,
+                                              T.Range.getBegin()))
+                    .first;
+    auto &AC = Iter->second;
     if (auto Err = AC.replace(*Result.SourceManager, T.Range, T.Replacement)) {
       Consumer(std::move(Err));
       return;
     }
   }
 
-  for (const auto &I : Case.AddedIncludes) {
-    auto &Header = I.first;
-    switch (I.second) {
-    case transformer::IncludeFormat::Quoted:
-      AC.addHeader(Header);
-      break;
-    case transformer::IncludeFormat::Angled:
-      AC.addHeader((llvm::Twine("<") + Header + ">").str());
-      break;
+  for (auto &IDChangePair : ChangesByFileID) {
+    auto &AC = IDChangePair.second;
+    // FIXME: this will add includes to *all* changed files, which may not be
+    // the intent. We should upgrade the representation to allow associating
+    // headers with specific edits.
+    for (const auto &I : Case.AddedIncludes) {
+      auto &Header = I.first;
+      switch (I.second) {
+      case transformer::IncludeFormat::Quoted:
+        AC.addHeader(Header);
+        break;
+      case transformer::IncludeFormat::Angled:
+        AC.addHeader((llvm::Twine("<") + Header + ">").str());
+        break;
+      }
     }
-  }
 
-  Consumer(std::move(AC));
+    Consumer(std::move(AC));
+  }
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to